refactor(alembic): squash all migrations into clean initial_schema

- Replace 8 messy migration files (~2000+ lines) with single clean initial_schema (215 lines)
- All table comments defined inline at CREATE TABLE time (no more alter_column spam)
- Final table names used directly (mjk_broll_categories, etc. — no rename chain)
- Includes diagnosis report at docs/alembic-diagnosis-report.md
This commit is contained in:
小鱼开发
2026-05-15 17:35:54 +08:00
parent d71cfb8449
commit 542bc1f070
10 changed files with 396 additions and 981 deletions
+181
View File
@@ -0,0 +1,181 @@
# Alembic 迁移诊断报告
## 迁移历史概览
```
<base>
509aa8b53d81 initial_schema(创建 6 张初始表)
ccf61ff6f4bb remove_frozen_and_refunded(删除 3 个废弃字段)
95eb1a1c0af9 add_duration_to_point_transactionduration 字段)
8aa48b89a07d add_category_to_point_transactioncategory 字段)
69274ce979a5 add_broll_material_tables(⚠️ 问题脚本,593 行)
e02c96e264d9 add_cover_backgrounds_table(封面背景表)
d0a7c5a375c6 add_app_update_tables(更新系统表)
7a412121e69a rename_mjk_to_mjk_brollbroll 表重命名) ← head
```
依赖链:**线性,无 branch/merge**head 为 `7a412121e69a`
---
## 🔴 严重问题
### 1. 69274ce979a5 脚本职责混乱、极其臃肿
**脚本名**`add_broll_material_tables`
**实际内容**
- 创建 3 张新表(`mjk_categories`/`mjk_tags`/`mjk_materials`):约 60 行
- 给已有 6 张表的所有字段加 `comment`:约 530 行
**问题**
- 脚本体积膨胀到 **593 行**90% 内容和脚本名称无关
- 新环境执行迁移时,会触发几十个 `ALTER COLUMN` 操作,耗时显著增加
- 脚本难以维护,任何已有表字段的 comment 调整都需要修改这个脚本
- "加 comment" 和 "创建新表" 是完全独立的操作,不应该混在一起
**正确做法** hindsight ):
- 脚本 A:创建 broll 表(~60 行)
- 脚本 B:给已有字段补 comment~530 行)
- 或在 `initial_schema` 中直接带上 comment,避免后续回头补
---
### 2. "创建 → 加 comment → 重命名" 链式低效
| 步骤 | 迁移脚本 | 操作 |
|------|---------|------|
| 1 | 509aa8b53d81 | 创建 `mjk_categories`(无 comment |
| 2 | 69274ce979a5 | 给 `mjk_categories` 字段加 comment |
| 3 | 7a412121e69a | 重命名 `mjk_categories``mjk_broll_categories` |
**问题**:同一张表经历了"创建 → 补 comment → 重命名"三次操作。正确的做法是在创建时就用最终表名并带上 comment。
---
## 🟡 中等问题
### 3. downgrade 顺序错误
**d0a7c5a375c6**(更新系统表):
```python
# 当前(逻辑顺序错误)
op.drop_table("release_packages") # 1. 先删子表
op.drop_index("ix_app_releases_version", table_name="app_releases") # 2. 再删索引
op.drop_table("app_releases") # 3. 最后删父表
```
虽然 `drop_table` 会级联删除索引不会报错,但正确的逻辑顺序应该是:
```python
op.drop_table("release_packages")
op.drop_index("ix_app_releases_version", table_name="app_releases")
op.drop_table("app_releases")
```
> 注:当前顺序实际不会导致错误,只是不够规范。
### 4. 表名前缀不一致
| 表 | 前缀 | 一致性 |
|----|------|--------|
| `mjk_users` | `mjk_` | ✅ |
| `mjk_point_transactions` | `mjk_` | ✅ |
| `mjk_broll_categories` | `mjk_` | ✅ |
| `mjk_cover_backgrounds` | `mjk_` | ✅ |
| `app_releases` | `app_` | ❌ 缺少 `mjk_` 前缀 |
| `release_packages` | 无前缀 | ❌ 缺少 `mjk_` 前缀 |
### 5. 时间戳与顺序不一致
- `d0a7c5a375c6` Create Date`2026-05-11 09:30:00`
- `e02c96e264d9` Create Date`2026-05-11 20:00:00`
依赖链:`e02c96e264d9 → d0a7c5a375c6`,但时间戳显示 `e02c96e264d9``d0a7c5a375c6` 晚(20:00 vs 09:30)。
不影响功能,只是记录不规范。
---
## 🟢 正常部分
### 模型与迁移一致性 ✅
| 模型 | 表名 | 字段 | 状态 |
|------|------|------|------|
| `UserPoint` | `mjk_user_points` | 无 `frozen`/`total_refunded` | ✅ 与 `ccf61ff6f4bb` 一致 |
| `PointBatch` | `mjk_point_batches` | 无 `frozen` | ✅ 与 `ccf61ff6f4bb` 一致 |
| `PointTransaction` | `mjk_point_transactions` | 有 `duration` + `category` | ✅ 与 `95eb1a1c0af9`/`8aa48b89a07d` 一致 |
| `BrollCategory` | `mjk_broll_categories` | - | ✅ 与 `7a412121e69a` 重命名后一致 |
| `BrollMaterial` | `mjk_broll_materials` | - | ✅ 与 `7a412121e69a` 重命名后一致 |
| `BrollTag` | `mjk_broll_tags` | - | ✅ 与 `7a412121e69a` 重命名后一致 |
| `CoverBackground` | `mjk_cover_backgrounds` | - | ✅ 与 `e02c96e264d9` 一致 |
| `AppRelease`/`ReleasePackage` | `app_releases`/`release_packages` | - | ✅ 与 `d0a7c5a375c6` 一致 |
### env.py 模型导入 ✅
导入了全部 12 个模型类,无遗漏。
---
## 修复建议
### 方案 A:维持现状(推荐,已投产)
**理由**
- 生产环境数据库已有数据,不能直接修改或删除已有迁移脚本
- 当前迁移链虽然"丑",但功能正确,执行无误
**行动**
- 保留现有迁移,以后的新迁移保持**单一职责**(一个脚本只做一件事)
- 不再在迁移脚本里大量添加 `comment`(初始 schema 没带的就保持原样)
### 方案 B:Squash 迁移(适合新环境 / 大版本重构时)
将所有历史迁移合并为一张干净的 `initial_schema`
```bash
# 1. 备份当前 alembic 目录
mv alembic/versions alembic/versions_backup
# 2. 在空数据库上生成一张完整的初始迁移
alembic revision --autogenerate -m "squash: initial schema"
# 3. 验证新迁移包含所有表和字段
# 4. 删除备份
rm -rf alembic/versions_backup
```
**风险**
- 生产环境已有 `alembic_version` 记录,不能直接切换
- 需要协调所有环境(开发/测试/生产)同时切换
### 方案 C:拆分 69274ce979a5(仅做记录,不建议执行)
`69274ce979a5` 拆分为两个脚本:
1. `create_broll_tables`:创建 `mjk_broll_categories`/`mjk_broll_materials`/`mjk_broll_tags`
2. `add_column_comments`:给已有字段加 comment
**不可行原因**:已有迁移的 revision ID 已写入数据库 `alembic_version` 表,拆分会导致已执行环境的历史记录和脚本不匹配。
---
## 结论
| 问题 | 严重程度 | 是否可修复 | 建议 |
|------|---------|-----------|------|
| 69274ce979a5 职责混乱 | 🔴 高 | ❌ 已投产,不动 | 以后新迁移保持单一职责 |
| 创建→comment→重命名链 | 🔴 高 | ❌ 已投产,不动 | 以后在创建时直接用最终表名 |
| downgrade 顺序 | 🟡 中 | ⚠️ 不建议改 | 当前不会报错,保持现状 |
| 表名前缀不一致 | 🟡 中 | ❌ 已投产,不动 | 接受现状 |
| 时间戳不一致 | 🟢 低 | ❌ 无影响 | 忽略 |
**最终建议**:维持现状,不修改已有迁移脚本。以后新迁移遵循"单一职责原则"。