HarisNvr
@HarisNvr
Начинающий кодер Python

Как создать первые миграции в PostgreSQL, внутри Docker контейнера через Alembic?

Имеется функция ТГ бота, которая запускается каждый раз при запуске основного скрипта:

class Message(Base):
    __tablename__ = 'Message_ids'

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    chat_id: Mapped[int] = mapped_column(ForeignKey('Users.id'))
    message_id: Mapped[int] = mapped_column()
    date_added: Mapped[str] = mapped_column(
        default=current_time
    )

    user = relationship('User', back_populates='messages')

def morning_routine():
    """
    Delete old message IDs from the DB. Telegram's policy doesn't allow bots
    to delete messages that are older than 48 hours. Wake's up a little bit
    slow, to give the database time to fully load.
    :return: Nothing
    """

    sleep(5)
    threshold = datetime.now() - timedelta(hours=48)

    with Session(engine) as session:
        stmt = delete(Message).where(
            Message.date_added < threshold.strftime('%Y-%m-%d %H:%M:%S'))

        session.execute(stmt)
        session.commit()


Проблема такая, когда мы только первый раз деплоим бота, том с БД пуст и в нём нет ничего, соответственно лезет ошибка:

2024-08-04 17:34:09 sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "Message_ids" does not exist
2024-08-04 17:34:09 LINE 1: DELETE FROM "Message_ids" WHERE "Message_ids".date_added < '...
2024-08-04 17:34:09                     ^
2024-08-04 17:34:09 
2024-08-04 17:34:09 [SQL: DELETE FROM "Message_ids" WHERE "Message_ids".date_added < %(date_added_1)s]
2024-08-04 17:34:09 [parameters: {'date_added_1': '2024-08-02 11:34:09'}]
2024-08-04 17:34:09 (Background on this error at: https://sqlalche.me/e/20/f405)


Как можно красиво указать, чтобы бот чекал БД на предмет пустоты и если БД пуста - создавал Алембик миграцию, мигрировал её и ничего дальше не делал. А если при запуске база не пуста - то делал то, что сейчас описано в коде.

Я уже пробовал разные варианты - прописывать команды в докерфайле, создавать migrate.py, делать внутри функции через if или try - всё это в какой-то мере работало, но оч криво-косо.
  • Вопрос задан
  • 111 просмотров
Решения вопроса 1
HarisNvr
@HarisNvr Автор вопроса
Начинающий кодер Python
Немного отдохнув пришёл к такому решению:

def morning_routine():
    """
    Delete old message IDs from the DB. Telegram's policy doesn't allow bots
    to delete messages that are older than 48 hours. Wake's up a little bit
    slow, to give the database time to fully load.
    :return: Nothing
    """

    sleep(5)

    session = Session(engine)
    threshold = datetime.now() - timedelta(hours=48)
    stmt = delete(Message).where(
        Message.date_added < threshold.strftime('%Y-%m-%d %H:%M:%S')
    )

    try:
        session.execute(stmt)
        session.commit()
    except ProgrammingError:
        subprocess.run(
            'alembic revision --autogenerate -m "Initial migration"',
            shell=True
        )
        subprocess.run('alembic upgrade head', shell=True)
    finally:
        session.close()


Буду рад конструктивной критике!
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы