Зачем версионировать схему БД
Схема базы данных меняется по мере развития системы: новые таблицы, колонки, индексы. Без версионирования:
- На dev — одна схема, на prod — другая.
- Невозможно откатиться при неудачном обновлении.
- Непонятно, когда и какая колонка добавлена.
- Команда разработчиков не знает, в каком состоянии БД.
Alembic решает это: каждая миграция — ревизия с номером, можно применить и откатить.
Базовые команды
alembic upgrade head # применить все неприменённые миграции alembic downgrade -1 # откатить последнюю миграцию alembic current # текущая ревизия на prod alembic history # история миграций
Правило 1: Миграции должны быть обратимыми
Для каждой функции upgrade() пишем downgrade(). Если миграцию нельзя откатить — это не миграция, это точка невозврата.
def upgrade(): op.add_column('orders', sa.Column('status', sa.String(50), nullable=True)) def downgrade(): op.drop_column('orders', 'status')
Правило 2: Не блокировать таблицы
Некоторые операции блокируют таблицу на время миграции. На prod с активными пользователями — это остановка работы.
Плохо:
- ALTER TABLE ... ADD COLUMN ... DEFAULT ... — блокирует таблицу на больших объёмах.
- CREATE INDEX ... — блокирует запись.
Хорошо:
- ADD COLUMN без default — мгновенно. Default добавляется позже отдельной миграцией.
- CREATE INDEX CONCURRENTLY ... — не блокирует запись.
Правило 3: Не менять данные массово
Миграция схемы — это изменение структуры, не данных. Если нужно заполнить новую колонку для миллионов строк — это отдельный скрипт данных, не миграция.
Миграция: добавили колонку → скрипт данных: заполнили → миграция: добавили NOT NULL constraint.
Правило 4: Тестировать на копии prod
Перед применением на prod — восстанавливаем backup на тестовом сервере и применяем миграцию. Проверяем время выполнения и результат.
Процесс обновления в production
- Backup БД (pg_dump).
- Останавливаем приложение (или переводим в read-only).
- alembic upgrade head.
- Запускаем приложение.
- Проверяем health-check.
Если что-то пошло не так:
- alembic downgrade -1.
- Восстанавливаем приложение из предыдущей версии.
- Проверяем.
Что получает заказчик
- Все миграции в репозитории — история изменений схемы.
- Каждая миграция обратима.
- Обновление без остановки для склада/производства.
- Воспроизводимость: на любом сервере схема будет одинаковой.
Это базовый уровень инженерной культуры. Без версионирования миграций — система не готова к развитию.