Комментарии 8
Спасибо за статью!
Подскажите, пожалуйста, на счет файлов миграций. Получается, у нас alembic генерирует начальную версию и мы храним все дальнейшие миграции, а чтобы с нуля базу привести в нужное состояние, мы их накатываем одну за другой? Я просто Alembic пробовал использовать одно время, но постоянно возникали проблемы рассинхронизации. Хороших статей на тему маловато, поэтому как-то отошел от использования.
p.s. Вижу, что перевод. Возможно, кто-то другой ответит) спасибо.
Если грубо: alembic следит за моделями и сохраняет в своих версиях первоначальное состояние (первый запуск) и дифы, относительно предыдущего (последующие). У каждой итерации есть идентификатор, он присваивается как версия (в случае успешного апгрейда) целевой базе. Соответственно обновить состояние, относительно текущего, можно до любой из сохраненных итераций.
Если я правильно помню alembic сравнивает состояние с бд и накатывает чего не хватает
Зависит от состояния вашего проекта. Если есть активные пользователи, то да, нужно накатывать все миграционные скрипты. К счастью, алембик знает с какой версии обновляться и сам применяет только нужные скрипты.
Спасибо за статью! Как раз хотел попробовать sqlmodel для своих проектов (@^◡^)
Небольшое отступление по alembic: была создана модель с помощью sqlalchemy (декларативное отображение с наследованием от Base) и добавлено в неё несколько тестовых записей. Потом я захотел изменить структуру и накатить миграцию, но предыдущие данные не сохраняются. Что нужно предпринять, чтобы при миграции данные сохранялись? Исходя из анализа генерируемого файла alembic, в функции upgrade() он никак не подтягивает данные из предыдущей модели, а просто дропает таблицу, и создаёт снова
P.S. БД MySQL
Ух, спасибо!
Совсем забыл о существовании алембика) все ждал когда в документации SQLModel появится раздел с миграциями!
async def get_session()
Написан не правильно.
Во-первых зачем каждый раз создавать инстанс фабирки которая будет возвращать сессии. Это нужно сделать один раз как и с engine переменной.
Во-вторых, создание сессии на время жизни всего запроса к АПИ, может приводить к ошибкам. Например если нужно выполнить асинхронно несколько корутин внутри которых есть обращение к БД и для этого используется один инстанс сессии, полученный из зависимости. Особенной если хочется писать в "style 2.0" стиле готовя запросы через insert()/select()/update().
Так же стоит сказать что asyncpg который Алхимия использует для реализации асинхронных вызовов к БД не работает если БД "спрятана" за балансировщиком типа pgbouncer. Так как asyncpg имеет свой пул подключений от чего может возникать ошибка типа "prepared statement error" - https://magicstack.github.io/asyncpg/current/faq.html#why-am-i-getting-prepared-statement-errors
Как настроить SQLAlchemy, SQLModel и Alembic для асинхронной работы с FastAPI