Чинит alembic mismatch и аналогичные сюжеты с миграциями БД. Stamp на head, ALTER TABLE IF NOT EXISTS, safe migrate. Используй когда «миграция падает с DuplicateColumnError / DuplicateTableError / UndefinedColumnError», «alembic_version отстаёт от реальной БД», «rcstudio/mvc-backend в crashloop из-за миграции».
Пока нет рефлексий. Запиши через ~/.claude/bin/append-reflection.py после следующего вызова.
## INVARIANTS — never override 1. ВСЕГДА сначала **сделать backup** БД (`pg_dump -Fc`) до любых ALTER/UPDATE. 2. Никогда не делать `DROP TABLE` / `DROP COLUMN` без явного approval юзера. 3. Для production БД — только expand-contract pattern (RULES.md §6). Никаких разрушительных миграций. 4. `UPDATE alembic_version SET version_num='...'` — допустимо, только если все промежуточные таблицы реально существуют (проверять каждую). 5. Если структура БД сильно разошлась с моделями — `alembic stamp head` НЕ применять, идти по миграциям с `IF NOT EXISTS` patch'ами. ## Назначение Чинит типичные ситуации: - alembic_version отстаёт от реальной БД (миграция применилась руками или через другой backend) - Конфликт двух backend'ов на одну БД (как rcstudio + myvoicecraft на myvoicecraft DB) - DuplicateColumnError при auto-migration на startup - UndefinedColumnError когда модель ожидает поле, а в БД его нет ## Алгоритм ### Шаг 1: Диагностика ```sql SELECT version_num FROM alembic_version; \dt \d <suspected_table> ``` Сравнить с миграциями: `ls /app/alembic/versions/` + `grep -A 30 "def upgrade" <head>.py` ### Шаг 2: Backup ```bash docker exec <PG> pg_dump -U <USER> -Fc <DB> > /srv/backups/safety/<DB>-<ts>.dump ``` ### Шаг 3: Reconcile - Если **таблица есть, но alembic_version отстаёт** → `UPDATE alembic_version SET version_num='<intermediate>'` чтобы пропустить уже выполненную миграцию - Если **столбец отсутствует, но миграция think он есть** → ручной `ALTER TABLE ADD COLUMN IF NOT EXISTS` + stamp на head - Если **столбец есть, но миграция пытается добавить заново** → stamp на следующую ревизию после неё ### Шаг 4: Verify ```bash docker restart <CONTAINER> docker logs <CONTAINER> --tail 20 ``` ### Шаг 5: Document Создать `Topics/db-migrations-fixes.md` запись: - Что было сломано - Какой ALTER/UPDATE применил - Откатить можно через `pg_restore -Fc -c <backup>` ## Когда вызывать - Контейнер в Restarting loop из-за миграции - `sqlalchemy.exc.ProgrammingError: column X does not exist` - `DuplicateColumnError` / `DuplicateTableError` в логах - Два backend'а на одну БД с разными chain'ами миграций ## Когда НЕ вызывать - Для проектирования новой миграции (это `python-programmer`) - Если нужно реструктурировать БД (это `python-programmer` + `qa-engineer`) - Для DROP/destructive changes — не делать вообще без явного approval Макса ## Связано - `RULES.md §6` (запрет на `DROP COLUMN` без expand-contract) - `memory/session_2026-05-25_evening.md` — пример починки rcstudio - `memory/session_2026-05-25_full-day.md` — пример починки calendar_entries ## LEARNED (auto-updated by agent-self-improve) (пока пусто)