Alembic предлагает drop_table: проверьте импорт моделей

После добавления модели autogenerate создал неожиданную миграцию: новая таблица не появилась, зато существующие предлагается удалить. База подключена правильно, история revision выглядит целой. Часто проблема в том, что env.py передаёт metadata, в котором нужные классы ещё не зарегистрированы.

Alembic сравнивает отражённую схему базы с target_metadata. Declarative-класс добавляет таблицу в metadata при выполнении определения класса, то есть при импорте модуля. Импорт одного Base не означает импорт всех моделей проекта. Если metadata неполон, сравнение трактует отсутствующие таблицы как лишние в базе.

Как изменить решение

# alembic/env.py
from app.db.base import Base
from app.models import customer, order  # регистрирует mapped-классы

target_metadata = Base.metadata
expected = {'customers', 'orders'}
missing = expected - set(target_metadata.tables)
if missing:
    raise RuntimeError(f'Model metadata is incomplete: {sorted(missing)}')

# В context.configure используется именно этот объект:
# context.configure(connection=connection, target_metadata=target_metadata)

До запуска сравнения можно увидеть неполный набор таблиц и остановиться с понятной ошибкой. Пример предполагает один Base и таблицы без schema. В проекте с именованными схемами ключи metadata включают схему, а при нескольких Base надо передать все нужные metadata.

Не применяйте сгенерированный drop_table, пока не объясните его появление. Исправьте импорты, проверьте адрес целевой базы и создайте корректный кандидат миграции. Autogenerate помогает составить изменения, но файл revision остаётся кодом, который разработчик читает перед запуском.

Что проверить на своих данных

Выведите sorted(Base.metadata.tables) в отдельном диагностическом запуске с теми же импортами, что использует env.py. Затем сравните результат до и после импорта app.models.order. На копии схемы сгенерируйте миграцию без реальных изменений: в ней не должно быть неожиданных удалений.

Если база содержит таблицы других сервисов, полный импорт собственных моделей не решает вопрос владения схемой. Настройте include_name или другую явную фильтрацию объектов, чтобы Alembic сравнивал только управляемую область. Не фильтруйте удаления слепо по имени операции: так можно скрыть запланированное изменение. Полезно разделить две проверки: metadata действительно содержит все ваши модели, а отражение базы не включает чужие таблицы. Тогда причина опасного diff становится видимой до выполнения DDL.

Практика дальше

Чтобы metadata отражала понятную модель приложения, полезно собрать проект целиком. Курс FastAPI проходит путь от первого эндпоинта до backend с SQLAlchemy, авторизацией и pytest. База практики — SQLite; вы связываете модели, обработчики и тесты в одном приложении.

Посмотреть программу и практику курса

Источник: Alembic предлагает drop_table — официальная документация.

Другие задачи по теме: База, HTTP-клиенты и тесты API.

Продолжить на практике