2.5 KiB
2.5 KiB
Alembic 迁移规范
设计原则
0001仅服务全新库:create_all不会对已有表ALTER。老库缺列必须用0019及之后的显式迁移 补齐。- 一条迁移 = 明确 DDL:禁止用「全库 ORM 内省」替代清单;可审查、可测、各环境行为一致。
- 已部署的
revision永不改名:文件名可描述用途,但revision = "..."一旦上线不得修改。 - 新 ORM 字段同 PR 必须带迁移:改
models.py须同时alembic/versions/新增或扩展迁移(见 CI 测试)。
当前链
0001_initial → … → 0018_users_language_preference → 0019_align_legacy_schema (head)
0019_align_legacy_schema 维护「老库相对 0001 squash 常缺」的列清单,见 alembic/versions/0019_align_legacy_schema.py 内 _LEGACY_COLUMNS。
新增字段流程
- 修改 ORM
models.py - 若表在 squash 前就存在且 0002–0018 未覆盖该列 → 在
0019的_LEGACY_COLUMNS追加一行(未部署前),或新建0020_<short_desc>.py - 本地:
uv run alembic upgrade head - 提交前:
uv run pytest tests/test_alembic_migration_policy.py
Staging / Production 发布
| 环境 | 代码来源 | 说明 |
|---|---|---|
| Staging | main push |
迁移在容器启动时 upgrade head |
| Production | tag v*.*.* |
发 tag 前确认 staging 已成功跑过同一迁移链 |
生产推荐:ALEMBIC_STARTUP_FAIL_FAST=true,迁移失败则进程退出。
撤回错误迁移 0019/0020 后的库修复
若数据库 alembic_version 仍为已删除的 revision(例如 0020_add_tts_audio_urls_column 或 0020_backfill_missing_schema),部署新代码前先执行:
cd api
# 仅当 version_num 为已撤回的 0020_* 时
uv run python scripts/repair_alembic_version_after_withdrawn_0020.py
或手动 SQL(确认列已由旧迁移加过后再 stamp):
SELECT version_num FROM alembic_version;
-- 若为 0020_add_tts_audio_urls_column 或 0020_backfill_missing_schema:
UPDATE alembic_version SET version_num = '0018_users_language_preference';
然后部署;0019_align_legacy_schema 会幂等补齐缺列。
禁止事项
- 修改已上线 migration 的
revision/down_revision - 用
0020_backfill_*式全表内省替代显式列清单 - 只在 ORM 加字段、指望
create_all更新线上老库 - Staging 与 Production 长期使用不同迁移链(应同一 commit / 同一 tag 构建)