# 数据库字段重命名:metadata → meta_data **日期**: 2026-02-03 **类型**: 架构优化 **影响范围**: 数据库模型、Schema、Service、API **迁移文件**: `20260203_1521_9a6a8471bda0_rename_metadata_to_meta_data_and_add_ai_conversations.py` ## 背景 在实现 Screenplay 和 AI Conversation 功能时,发现使用 `metadata` 作为字段名会与 SQLAlchemy 的保留属性冲突,导致服务启动失败。 ### 问题 ```python # ❌ 错误:metadata 是 SQLAlchemy 保留字段 class ScreenplayCharacter(SQLModel, table=True): metadata: Dict[str, Any] = Field(...) # 与 SQLModel.metadata 冲突 ``` ### 解决方案 将所有 `metadata` 字段重命名为 `meta_data`,避免与 SQLAlchemy 保留字段冲突。 ## 变更内容 ### 1. 数据库字段重命名 **涉及表**: - `screenplay_characters.metadata` → `meta_data` - `screenplay_locations.metadata` → `meta_data` - `screenplay_props.metadata` → `meta_data` - `screenplay_element_tags.metadata` → `meta_data` - `ai_conversations.metadata` → `meta_data` - `ai_conversation_messages.metadata` → `meta_data` ### 2. 新增表 同时在此次迁移中创建了 AI Conversation 相关表: - `ai_conversations` - AI 对话会话表 - `ai_conversation_messages` - AI 对话消息表 ### 3. 代码层修改 **模型文件**(6个): - `server/app/models/screenplay_character.py` - `server/app/models/screenplay_location.py` - `server/app/models/screenplay_prop.py` - `server/app/models/screenplay_element_tag.py` - `server/app/models/ai_conversation.py` - `server/app/models/ai_conversation_message.py` **Schema 文件**(4个): - `server/app/schemas/screenplay.py` - `server/app/schemas/screenplay_tag.py` - `server/app/schemas/ai_conversation.py` - `server/app/schemas/ai_conversation_message.py` **Service 文件**(3个): - `server/app/services/screenplay_service.py` - `server/app/services/screenplay_tag_service.py` - `server/app/services/ai_conversation_service.py` **API 文件**(4个): - `server/app/api/v1/screenplays.py` - `server/app/api/v1/screenplay_tags.py` - `server/app/api/v1/ai_conversations.py` - `server/app/api/v1/ai_prompts.py` ## 技术细节 ### 字段定义 ```python # 新的字段定义 meta_data: Dict[str, Any] = Field( default_factory=dict, sa_column=Column(JSONB, nullable=False, server_default='{}'), description="元数据" ) ``` ### 命名优势 1. **避免保留字冲突**:`meta_data` 不是 SQLAlchemy 保留字段 2. **语义清晰**:明确表示"元数据" 3. **符合规范**:使用 snake_case 命名,符合 Python 社区规范 4. **更少混淆**:不会与 SQLAlchemy 的 `metadata` 属性冲突 ## 迁移步骤 ### 1. 数据库迁移 ```bash # 应用迁移 docker exec jointo-server-app python scripts/db_migrate.py upgrade ``` ### 2. 验证 ```bash # 检查字段名 docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\d screenplay_characters" # 验证服务启动 docker restart jointo-server-app docker logs jointo-server-app --tail 20 ``` ## 影响评估 ### 破坏性变更 - ✅ 数据库字段名变更(通过迁移自动处理) - ✅ API 请求/响应字段名变更(前端需同步更新) ### 兼容性 - ✅ 现有数据自动迁移 - ✅ 服务正常启动 - ⚠️ 前端代码需要同步更新字段名 ## 后续工作 1. **前端同步**:更新前端代码中所有 `metadata` 字段为 `meta_data` 2. **API 文档**:更新 API 文档中的字段说明 3. **测试验证**:确保所有相关功能正常工作 ## 经验教训 1. **避免使用保留字**:在设计数据库字段时,应避免使用框架的保留字段名 2. **提前验证**:在实现功能前,应先验证字段名是否会产生冲突 3. **统一命名规范**:使用 `snake_case` 命名,避免与框架内置属性冲突 ## 参考 - SQLAlchemy 保留字段:https://docs.sqlalchemy.org/en/20/core/metadata.html - Jointo 技术栈规范:`docs/architecture/tech-stack.md`