# 修复数据库迁移脚本 - 废弃表引用问题 **类型**: Bug 修复 **日期**: 2026-02-14 **影响范围**: 数据库迁移系统 ## 问题描述 数据库初始化失败,错误信息: ``` relation "screenplay_characters" does not exist ``` 应用启动时迁移执行报错,导致所有需要数据库的 API 返回 500 错误。 ## 根本原因 1. **重复迁移文件**:存在两个相同 revision ID 的迁移文件 - `20260214_1214_add_thumbnail_url_to_storyboard_videos.py` - `20260214_1214_d1446f0f5918_add_thumbnail_url_to_storyboard_videos.py` 2. **废弃表引用**:迁移 `20260205_1156_72966791b2f1_fix_time_fields_functions_and_triggers.py` 尝试为已废弃的表创建触发器 - `drop_screenplay_tables` 迁移删除了 `screenplay_characters`、`screenplay_locations`、`screenplay_props` 三张表 - 但 `20260205_1156` 仍在尝试为这些表创建 `updated_at` 触发器 ## 解决方案 ### 1. 删除重复迁移文件 删除了重复的迁移文件: ```bash rm server/alembic/versions/20260214_1214_d1446f0f5918_add_thumbnail_url_to_storyboard_videos.py rm -rf server/alembic/versions/__pycache__/ ``` ### 2. 修复迁移脚本 修改 `20260205_1156_72966791b2f1_fix_time_fields_functions_and_triggers.py`: **变更内容**: - 在创建触发器前添加表存在性检查 - 从触发器列表中移除废弃的三张表 - 更新 `trigger_name` 判断条件,移除废弃表的引用 **upgrade() 函数修改**: ```python for table in tables_with_updated_at: # 检查表是否存在(screenplay_* 表可能已被删除) conn = op.get_bind() result = conn.execute(sa.text(f""" SELECT EXISTS ( SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = '{table}' ); """)) table_exists = result.scalar() if not table_exists: print(f" ⚠️ 跳过不存在的表: {table}") continue # 只为 project_resources 和 screenplays 使用 trigger_ 前缀 trigger_name = f"update_{table}_updated_at" if table in ['project_resources', 'screenplays']: trigger_name = f"trigger_update_{table}_updated_at" # ... 创建触发器 ... ``` **downgrade() 函数同步修改**。 ## 测试结果 ### 迁移执行成功 ```bash $ docker exec jointo-server-app alembic current 20260214_1214 (head) ``` ### API 正常响应 ```bash $ curl http://localhost:6170/api/v1/users/me \ -H 'Authorization: Bearer xxx' { "success": false, "code": 401, "message": "无效的认证凭证或 Token 已过期", "data": null, "timestamp": "2026-02-14T05:05:20.037199+00:00" } ``` 返回 401 认证错误(业务逻辑正常),不再是 500 服务器错误。 ## 涉及文件 ### 修改 - `server/alembic/versions/20260205_1156_72966791b2f1_fix_time_fields_functions_and_triggers.py` ### 删除 - `server/alembic/versions/20260214_1214_d1446f0f5918_add_thumbnail_url_to_storyboard_videos.py` ## 后续建议 1. **迁移文件命名规范**:避免手动创建迁移文件,统一使用 `alembic revision` 命令生成 2. **定期清理**:定期清理 `__pycache__` 目录,避免缓存旧版本 3. **迁移测试**:重大迁移前在干净容器中测试,确保从头开始的迁移链完整 4. **废弃表清理**:删除表前检查是否有其他迁移引用该表 ## 相关文档 - ADR 006: TIMESTAMPTZ 时间戳规范 - 迁移指南: `docs/server/guides/database-migration.md`