You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.8 KiB
5.8 KiB
剧本数据库迁移完成总结
完成日期:2026-02-03
任务类型:数据库迁移补充
任务背景
根据 screenplay-file-parser-service.md 文档中定义的剧本文件解析服务需求,补充创建完整的数据库表结构。
已完成工作
1. 创建数据库迁移文件
文件:server/alembic/versions/20260203_1200_create_screenplays_tables.py
内容:
- ✅ 创建
screenplays表(剧本主表) - ✅ 创建
screenplay_tags表(剧本元素标签表) - ✅ 完整的索引策略(包括全文搜索)
- ✅ 数据完整性约束
- ✅ 自动更新触发器
- ✅ 完整的表/列注释
2. 创建 Changelog 文档
文件:docs/architecture/changelogs/2026-02-03-screenplays-tables-creation.md
内容:
- ✅ 完整的表结构说明
- ✅ 设计原则说明
- ✅ 使用示例代码
- ✅ 后续工作清单
- ✅ 测试建议
3. 更新服务文档
文件:docs/requirements/backend/04-services/project/screenplay-file-parser-service.md
变更:
- ✅ 移除"数据库字段扩展"章节
- ✅ 添加"数据库表结构"章节
- ✅ 引用迁移文件和 Changelog
技术规范符合性
✅ 完全符合 jointo-tech-stack 规范
- UUID v7:所有主键使用 UUID v7(应用层生成)
- TIMESTAMPTZ:所有时间字段使用
TIMESTAMP(timezone=True) - SMALLINT 枚举:类型字段使用 SMALLINT 存储枚举值
- 应用层外键:无物理外键约束,应用层保证引用完整性
- 索引策略:合理使用 B-Tree、GIN、部分索引
- 触发器:自动更新 updated_at 字段
- 注释规范:完整的表级和列级注释
✅ 支持文档中定义的所有功能
-
文件解析状态管理:
- idle (0) - 未解析
- pending (1) - 待解析
- parsing (2) - 解析中
- completed (3) - 已完成
- failed (4) - 失败
-
多种剧本类型:
- type=1 (file) - 上传文件
- type=2 (manual) - 手动输入
-
文件格式支持:
- TXT、Markdown(同步解析)
- DOCX、PDF、RTF、DOC(异步解析)
-
全文搜索:
- 剧本名称搜索
- 剧本内容搜索
- 元素名称搜索
- 标签名称搜索
表结构概览
screenplays 表
screenplay_id (UUID v7, PK)
├── project_id (UUID)
├── name (TEXT)
├── type (SMALLINT: 1=file, 2=manual)
├── file_url, file_name, file_size, mime_type (文件信息)
├── content (TEXT, Markdown)
├── word_count (INTEGER)
├── parsing_status (SMALLINT: 0-4)
├── parsing_error (TEXT)
├── parsed_at (TIMESTAMPTZ)
├── display_order (INTEGER)
├── created_at, updated_at, deleted_at (TIMESTAMPTZ)
索引:7 个(包括 2 个全文搜索索引)
约束:4 个(类型、状态、字数、内容完整性)
触发器:1 个(自动更新 updated_at)
screenplay_tags 表
tag_id (UUID v7, PK)
├── screenplay_id (UUID)
├── element_type (SMALLINT: 1=character, 2=scene, 3=prop, 4=sound, 5=other)
├── element_name (TEXT)
├── tag_label (TEXT)
├── description (TEXT)
├── metadata (JSONB)
├── display_order (INTEGER)
├── created_at, updated_at (TIMESTAMPTZ)
索引:7 个(包括 2 个全文搜索索引)
约束:2 个(元素类型、唯一性)
触发器:1 个(自动更新 updated_at)
后续工作
必须完成(阻塞功能开发)
-
创建 Model 类
server/app/models/screenplay.pyserver/app/models/screenplay_tag.py
-
创建 Repository 类
server/app/repositories/screenplay_repository.pyserver/app/repositories/screenplay_tag_repository.py
-
创建 Schema 类
server/app/schemas/screenplay.py
可选完成(增强功能)
-
完善 Service 类
- 补充
ScreenplayFileParserService的数据库操作 - 创建
ScreenplayService - 创建
ScreenplayTagService
- 补充
-
创建 API 路由
server/app/api/v1/screenplays.pyserver/app/api/v1/screenplay_tags.py
-
创建 Celery 任务
server/app/tasks/screenplay_tasks.py
测试验证
数据库迁移测试
# 升级到最新版本
docker exec jointo-server-app alembic upgrade head
# 验证表结构
docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\d screenplays"
docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\d screenplay_tags"
# 查看索引
docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\di screenplays*"
docker exec jointo-server-postgres psql -U jointoAI -d jointo -c "\di screenplay_tags*"
# 降级测试
docker exec jointo-server-app alembic downgrade -1
docker exec jointo-server-app alembic upgrade head
约束测试
-- 测试类型约束(应失败)
INSERT INTO screenplays (screenplay_id, project_id, name, type)
VALUES (gen_random_uuid(), gen_random_uuid(), 'Test', 3);
-- 测试内容完整性约束(应失败)
INSERT INTO screenplays (screenplay_id, project_id, name, type)
VALUES (gen_random_uuid(), gen_random_uuid(), 'Test', 1);
-- 测试唯一约束(应失败)
INSERT INTO screenplay_tags (tag_id, screenplay_id, element_type, element_name, tag_label)
VALUES
(gen_random_uuid(), 'xxx', 1, '孙悟空', '少年'),
(gen_random_uuid(), 'xxx', 1, '孙悟空', '少年');
相关文档
完成日期:2026-02-03
状态:✅ 数据库迁移已完成,等待 Model/Repository/Service 实现