Alembic autogenerate хочет удалить колонку: проверяем переименование

В модели пользователя поле full_name переименовали в display_name. Код стал понятнее, тесты на новой пустой базе проходят. Затем autogenerate предлагает удалить full_name и добавить display_name. Для пустой таблицы разницы почти нет. Для базы с тысячами имён это уже потеря данных.

Alembic сравнивает описание схемы с существующей базой. По одному исчезнувшему и одному появившемуся имени нельзя надёжно понять намерение автора: это переименование или два независимых изменения. Поэтому сгенерированный файл надо читать как предложение изменений.

На что смотреть в upgrade

Вот подозрительная пара операций в миграции:

op.add_column("users", sa.Column("display_name", sa.String(120)))
op.drop_column("users", "full_name")

Если задача именно в переименовании, для PostgreSQL можно выразить его явно. Ниже тела функций для ревизии, где остальные изменения отсутствуют:

from alembic import op

def upgrade():
    op.alter_column("users", "full_name", new_column_name="display_name")

def downgrade():
    op.alter_column("users", "display_name", new_column_name="full_name")

Идентификаторы revision и down_revision сохраните из созданного файла. Для других СУБД проверьте поддерживаемую операцию и требования к existing_type; не переносите PostgreSQL-пример вслепую. SQLite в некоторых сценариях требует batch-миграции.

Проверка на данных, а не только на структуре

Создайте отдельную тестовую базу на предыдущей ревизии. Добавьте несколько строк с разными именами, запишите их id и значения. Примените миграцию и сравните пары id → display_name с исходными. После этого запустите код приложения, который читает и обновляет новое поле.

Если нужен рабочий downgrade, проверьте и обратный путь на тестовой копии. Успешный upgrade не доказывает, что downgrade сохранит данные после дальнейших записей приложения.

А что будет во время постепенного обновления

Прямое переименование может сломать старые экземпляры приложения: они ещё обращаются к full_name. Для обновления без одновременной остановки всех экземпляров часто удобнее несколько релизов. Сначала добавляют совместимое поле и продумывают синхронизацию записей, затем переносят чтение, и лишь после ухода старого кода удаляют прежнее поле.

Это уже задача совместимости двух версий приложения, а не только генерации SQL. Начните с простого вопроса: будет ли старый процесс ещё работать после изменения схемы? Ответ определяет, достаточно ли одной миграции.

Если два разработчика подготовили независимые изменения, следующая возможная остановка — несколько head в истории Alembic.

Собрать следующий этап проекта

Хотите собрать API целиком, а не останавливаться на отдельном обработчике? На бесплатном курсе FastAPI вы сделаете сервис с базой, регистрацией, проверкой прав и тестами. Это проект, который можно развивать дальше и показывать вместе с исходниками.

Посмотреть программу: FastAPI для начинающих: API с базой данных и тестами

Проверить детали: Alembic: возможности autogenerate, Alembic: alter_column.

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