Миграции базы данных — это версионированные скрипты, которые переводят схему БД из одного состояния в другое без ручных правок и без потери данных. Разберем, зачем они нужны, чем отличаются Alembic, Drizzle и Prisma migrate, и что делать, если миграция сломала продакшн.
В статье: разница между ручным ALTER TABLE и миграциями, пошаговая работа с тремя инструментами, откат при ошибке и защита миграций при работе с AI-агентами вроде Claude Code.
Миграции базы данных для новичка — это скрипты, которые фиксируют каждое изменение схемы отдельным файлом с номером версии, как коммиты в git. Alembic закрывает Python-стек, Drizzle и Prisma — Node.js. Главное правило: перед любой миграцией в проде делайте бэкап и коммит кода, иначе откатывать будет нечего.
Что такое миграция базы данных простыми словами?
Миграция — это скрипт, который переводит схему БД из состояния А в состояние Б. Не сама база данных, а инструкция, как ее изменить: добавить таблицу, столбец или индекс.
Разработчик из туториала по Flyway формулирует это без лишних терминов: миграция — просто скрипт, который может быть на SQL, Bash или Python, и его единственная задача — сдвинуть состояние базы на шаг вперед. Каждая такая инструкция хранится отдельным файлом с номером версии, а инструмент миграций держит в самой базе служебную таблицу, где записано, какие версии уже применены.
Представьте git, только не для кода, а для структуры таблиц. Вы меняете модель в коде — приложению нужен новый столбец. Без миграции вы либо лезете в базу руками через SQL-консоль, либо просите коллегу сделать то же самое у себя. Первое чревато опечаткой в проде, второе — рассинхроном между разработчиками. Миграция решает обе проблемы одним файлом, который лежит в репозитории рядом с кодом.

Зачем нужны миграции если можно менять таблицы руками?
Ручной ALTER TABLE работает, пока над проектом работает один человек и один сервер. С командой и несколькими окружениями ручные правки превращаются в рассинхрон схемы и потерю данных.
Как только приложение выходит за пределы одного ноутбука, схема базы становится такой же зависимостью, как и версия библиотеки. Один разработчик добавил столбец локально, второй не знает об этом — при деплое приложение падает, потому что код ждет поле, которого нет в проде. Миграции хранят историю изменений в git вместе с кодом, поэтому CI/CD просто накатывает недостающие версии на каждое окружение по очереди.
Есть и вторая причина, более практическая. Если менять NOT NULL поле руками, легко забыть про уже существующие строки — база откажется применять ограничение, потому что старые записи не проходят проверку. Миграционный инструмент заставляет explicit прописать, что делать со старыми данными: задать дефолт, заполнить их скриптом, потом уже убрать дефолт. Без этой дисциплины ошибку находят не на этапе разработки, а в проде, когда деплой падает посреди ночи.

Alembic Drizzle или Prisma что выбрать для вайбкодинга?
Alembic — для Python и SQLAlchemy. Drizzle — легковесный TypeScript-инструмент без генерации кода. Prisma — более «магический» ORM с собственным DSL для схемы. Выбор зависит от стека, а не от того, какой инструмент «лучше».
Если вы собираете бэкенд через Claude Code или Cursor на Python и FastAPI, Alembic идет вместе с SQLAlchemy почти автоматически. Для Node.js и TypeScript-стека выбор обычно между Drizzle и Prisma — оба генерируют SQL-миграции из схемы в коде, но по-разному.
| Инструмент | Стек | Как задается схема | Кодогенерация | Особенность |
|---|---|---|---|---|
| Alembic | Python + SQLAlchemy | Python-классы моделей | Нет отдельного клиента, миграции — тоже Python-файлы | Автогенерация через alembic revision --autogenerate |
| Drizzle ORM | TypeScript / Node.js | TypeScript-объекты в schema.ts | Нет, прямые типизированные запросы | Легкий, миграции — обычные SQL-файлы, есть Drizzle Studio для просмотра БД |
| Prisma | TypeScript / Node.js | Собственный DSL в schema.prisma | Да, генерирует клиент с типами | migrate dev для разработки, migrate deploy для продакшна |
Для вайбкодера без бэкграунда в бэкенде разница ощущается на старте: Drizzle ближе к «чистому» SQL и понятнее, если вы уже видели устройство таблиц. Prisma берет часть решений на себя, но за счет собственного языка описания схемы — придется выучить еще один синтаксис поверх TypeScript.

Как работает Alembic пошагово?
Alembic хранит миграции как Python-файлы с функциями upgrade и downgrade. Основной цикл — autogenerate, upgrade head, при ошибке downgrade на нужную версию.
Схема работы простая и почти одинаковая в любом проекте. Сначала alembic init создает папку с миграциями и конфиг alembic.ini, куда прописывается строка подключения к базе через sqlalchemy.url. Дальше в env.py нужно передать Base.metadata в target_metadata — именно отсюда Alembic узнает, какие модели у вас вообще есть.
Когда модели готовы, команда alembic revision --autogenerate -m "add email to user" сравнивает текущую схему базы с моделями в коде и сама пишет файл миграции с функциями upgrade() и downgrade(). Накатить изменения — alembic upgrade head, откатить последний шаг — alembic downgrade -1, откатить всё — alembic downgrade base.
Есть нюанс, который часто ловит новичков: автогенерация иногда не замечает изменение server_default у столбца. Для таких случаев в alembic revision --autogenerate добавляют флаг compare_server_default=True, иначе миграция сгенерируется, но не будет содержать изменение, которое вы на самом деле хотели внести. Если нужно вставить сырой SQL руками, для этого есть op.execute() — миграция не обязана быть только автогенерацией.

Как сделать первую миграцию в Drizzle ORM?
Drizzle описывает таблицы как TypeScript-объекты в schema.ts, а команда drizzle-kit generate превращает их в обычный SQL-файл миграции, который потом накатывается командой migrate.
Типичная связка для Node.js-стека — PostgreSQL в Docker плюс Drizzle поверх него. Схема пользователей и постов описывается прямо в TypeScript: указываете тип поля, ограничения вроде unique на email, on delete cascade для внешнего ключа, индексы для полей, по которым часто идет выборка. Никакого отдельного языка описания — это обычный TypeScript-код, который тайпчекается вместе с остальным проектом.
После того как схема готова, drizzle-kit generate сравнивает ее с текущим состоянием и сохраняет SQL-файл миграции в отдельную папку. Применить изменения к базе — drizzle-kit migrate. Смотреть, что в итоге получилось в базе, удобно через Drizzle Studio или через Adminer, если он поднят рядом в docker-compose. Для проекта на Claude Code или Cursor такая связка удобна тем, что весь docker-compose с базой и админкой можно поднять одной командой на любой машине.
Отдельный лайфхак для сидинга тестовых данных: используйте onConflict('doUpdate', ...) вместо простого insert. Скрипт заполнения базы становится идемпотентным — его можно гонять сколько угодно раз, он не упадет на повторном запуске и не создаст дубликаты.
А что с Prisma migrate?
Prisma использует собственный файл schema.prisma для описания моделей, а миграциями управляют команды migrate dev для разработки и migrate deploy для продакшна.
Prisma устроена похоже на Alembic и Drizzle в главном: схема описывается декларативно, а миграции генерируются автоматически на основе разницы между схемой и базой. Разница — в разделении команд под окружения. prisma migrate dev создает и сразу применяет миграцию локально, попутно пересобирая Prisma Client с новыми типами. В проде используется prisma migrate deploy — она только накатывает уже существующие миграции без создания новых, что важно: в CI/CD никогда не должно происходить автогенерации на живых данных.
Если миграция в проде зависла или упала на середине, prisma migrate resolve позволяет вручную пометить ее как примененную или откаченную, не трогая саму базу еще раз. Это тот самый случай, где лучше на минуту остановиться и прочитать, что реально произошло в базе, а не жать команды подряд.

Как откатить миграцию если что-то пошло не так?
Формальный откат через downgrade работает для последних версий, но общая рекомендация индустрии — «fail forward»: чинить проблему новой миграцией, а не откатывать старую.
У всех трех инструментов есть команда отката: alembic downgrade, откат последней Drizzle-миграции вручную через SQL, prisma migrate resolve --rolled-back. Но на практике опытные разработчики советуют относиться к откату так же, как к откату git-коммита в проде: это крайняя мера. Если проблема обнаружилась после того, как на новую схему уже успели записаться данные, откат может стереть их так же, как стерла бы ручная правка.
Более безопасный путь — написать новую миграцию, которая чинит проблему вперед: возвращает столбец, поправляет тип, заполняет данные скриптом. Так история изменений остается честной и последовательной, и в логе миграций видно, что именно пошло не так и как это исправили, а не просто пустоту на месте отката.

Как защитить миграции при работе с Claude Code?
Если бэкенд собирается через AI-агента, папку с миграциями стоит защитить хуком, который блокирует запись в нее без подтверждения человека.
Для вайбкодера, который поручает бэкенд Claude Code или Cursor, актуальный риск не в самих миграциях, а в том, что агент может отредактировать уже примененный файл миграции вместо создания нового. В официальной документации Claude Code прямо приводят пример промпта для настройки защиты: «write a hook that blocks writes to the migrations folder» — то есть попросить агента самого написать хук, который не даст ему же переписывать файлы в папке миграций без вашего подтверждения.
Хук — это не совет в стиле CLAUDE.md, который агент может проигнорировать, а жесткое правило: если условие не выполнено, действие просто не происходит. Для вайбкодинга это особенно важно, потому что агент за одну сессию может внести десятки правок, и без такого ограничения легко не заметить, что он тихо отредактировал старую миграцию вместо новой.
Максим: «Поделюсь болезненным лайфхаком. Один раз удалил базу пользователей, бэкапа не было, данные пропали навсегда. С тех пор в любом проекте, который собираю через вайбкодинг, бэкап и коммит перед миграцией — это не опция, это правило номер один. Даже когда кажется, что изменение мелкое.»

Какие ошибки чаще всего допускают новички с миграциями?
Главные ошибки: нет бэкапа перед миграцией, редактирование уже примененного файла вместо новой миграции, добавление NOT NULL без дефолта для старых строк, забытый коммит миграции в git.
Список набирается почти одинаковый в любом стеке:
- Меняют схему руками через SQL-консоль «на скорую руку», а потом забывают перенести то же самое в код миграции.
- Правят уже примененный файл миграции вместо того, чтобы создать новый — у остальных разработчиков и в проде версия истории расходится.
- Добавляют
NOT NULLстолбец без дефолтного значения, хотя в таблице уже есть строки — миграция падает на существующих данных. - Не коммитят файл миграции вместе с изменением кода — при деплое приложение ждет поле, которого еще нет в базе.
- Запускают автогенерацию прямо на проде вместо
deployкоманды, которая только применяет готовые миграции.
Готовый промпт, если хотите доверить создание миграции AI-агенту, а не писать руками:
Создай миграцию для добавления поля [название] типа [тип] в таблицу [таблица].
Python + Alembic: alembic revision --autogenerate -m 'add [field] to [table]' / alembic upgrade head / alembic downgrade -1
Node.js + Drizzle: npx drizzle-kit generate / npx drizzle-kit migrate
Покажи: как выглядит сгенерированный файл миграции, как применить, как откатить.
Перед миграцией сделай git commit, чтобы можно было откатить код вместе с базой.
Кому какой инструмент выбрать: итоговая карта
| Ситуация | Что выбрать |
|---|---|
| Бэкенд на Python, FastAPI, SQLAlchemy | Alembic |
| Node.js-стек, хочется минимум магии и прямой SQL | Drizzle ORM |
| Node.js-стек, важна готовая типизация и быстрый старт | Prisma |
| Бэкенд собирает Claude Code или Cursor | Любой из трех + хук на блокировку записи в папку миграций |
| Первая миграция для уже существующей базы | Baseline-команда инструмента, а не миграция с нуля |
Каталог инструментов для сборки бэкенда, включая обзоры IDE, которые умеют генерировать такие миграции сами, смотрите в каталоге AI-инструментов VibeCoderz. Если бэкенд и инфраструктуру закрывает не один человек, а часть команды, посмотрите на агента для DevOps-задач в каталоге — там собраны ниши именно под настройку окружений и CI/CD.
Частые вопросы про миграции базы данных
Что будет если не делать миграции, а менять базу руками?
Локально ничего страшного не случится. Проблемы начинаются с деплоем: код на проде ждет схему, которую вы правили только у себя, приложение падает при первом запросе к новому полю.
Можно ли редактировать уже примененную миграцию?
Не стоит. Если файл миграции уже накатан хотя бы на одном окружении, правьте его через новую миграцию, а не переписывайте старую — иначе история изменений разойдется между окружениями.
Что делать если миграция упала на середине?
Сначала проверить состояние базы вручную, не гнать команды подряд. У Alembic и Drizzle это через downgrade, у Prisma — через migrate resolve, которая помечает миграцию примененной или откаченной без повторного изменения данных.
Нужен ли бэкап перед каждой миграцией?
Перед миграцией в проде — да, всегда. Для локальной разработки это не критично, но привычка делать git commit перед миграцией экономит нервы в обоих случаях.
Чем автогенерация Alembic отличается от ручной миграции?
Автогенерация сравнивает модели с базой и сама пишет файл, но иногда пропускает детали вроде server_default. Ручная миграция через op.execute() дает полный контроль, когда автогенерация ошиблась.
Что такое baseline и когда он нужен?
Baseline — способ подключить миграции к уже существующей базе без потери данных. Инструмент экспортирует текущую схему в файл и помечает эту версию как «уже примененную», не выполняя ее заново.
Drizzle или Prisma — что быстрее для старта проекта?
Prisma дает готовую типизацию и клиент из коробки, старт получается быстрее. Drizzle ближе к чистому SQL, требует чуть больше ручной настройки, зато меньше «магии» под капотом.
Глоссарий
- Миграция — скрипт, который переводит схему базы данных из одного состояния в другое.
- Schema (схема) — структура таблиц, столбцов и связей в базе данных.
- Upgrade / downgrade — применение миграции вперед или откат назад на одну версию.
- Autogenerate — автоматическое создание файла миграции на основе разницы между моделями в коде и текущей базой.
- Baseline — точка отсчета для миграций в уже существующей базе без выполнения миграции заново.
- Seed — скрипт, который заполняет базу тестовыми или начальными данными.
- Idempotent-скрипт — скрипт, который можно запускать многократно без побочных эффектов, например через
upsert.
Разобраться, какой AI IDE лучше подходит для сборки бэкенда с нуля, поможет каталог инструментов VibeCoderz. Если нужна помощь с архитектурой конкретного проекта, запишитесь на консультацию к Максиму.
Обновлено: июль 2026.