Если ты до сих пор “правишь базу руками”, а потом ловишь рассинхрон между dev/stage/prod - остановись.
Правильная миграция БД должна быть:
✅ воспроизводимой
✅ версионируемой
✅ безопасной при откате
✅ без даунтайма (по возможности)
Ключевые правила миграций:
1) Каждое изменение = отдельная миграция (не правь историю)
2) Только вперёд: rollback делай отдельной миграцией
3) Миграции должны быть idempotent, если это возможно
4) Никаких “ALTER TABLE в обед” на проде
5) Разделяй schema и data миграции
6) Для больших таблиц - делай изменения по шагам (expand -> migrate -> contract)
Самый безопасный паттерн:
- Добавляешь новое поле/таблицу (expand)
- Пишешь код, который работает и со старым, и с новым
- Переносишь данные (migrate)
- Удаляешь старое (contract)
-- 1) таблица миграций (если нет инструмента)
create table if not exists schema_migrations (
version text primary key,
applied_at timestamptz not null default now()
);
-- 2) миграция: добавляем колонку безопасно
alter table users add column if not exists phone text;
-- 3) перенос данных (пример)
update users
set phone = regexp_replace(contact, '[^0-9+]', '', 'g')
where phone is null and contact is not null;
-- 4) фиксируем версию миграции
insert into schema_migrations(version)
values ('2026_01_21_add_users_phone')
on conflict do nothing;