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.
3.6 KiB
3.6 KiB
AI Prompt System 唯一约束修复
日期: 2026-02-04
类型: Bug Fix
影响范围: 数据库迁移、测试
问题描述
在运行 AI Prompt System 测试时发现数据库缺少 name + version 唯一约束,导致 test_create_duplicate_name_version 测试失败。
检查发现迁移文件 20260203_1521_9a6a8471bda0 中 upgrade 和 downgrade 函数的操作反了:
- upgrade() 删除了约束(应该是创建)
- downgrade() 创建了约束(应该是删除)
解决方案
1. 创建新迁移文件
创建迁移文件 20260204_1626_410fc8822148_add_ai_prompts_system_name_version_unique_constraint.py:
def upgrade() -> None:
"""升级数据库 - 添加 name+version 唯一约束"""
op.create_unique_constraint(
'ai_prompts_system_name_version_unique',
'ai_prompts_system',
['name', 'version']
)
def downgrade() -> None:
"""回滚数据库 - 删除 name+version 唯一约束"""
op.drop_constraint(
'ai_prompts_system_name_version_unique',
'ai_prompts_system',
type_='unique'
)
2. 清理重复数据
在运行迁移前,清理数据库中的重复数据:
-- 删除重复记录,保留最早创建的
DELETE FROM ai_prompts_system a
USING ai_prompts_system b
WHERE a.prompt_id > b.prompt_id
AND a.name = b.name
AND a.version = b.version;
删除了 26 条重复记录。
3. 运行迁移
docker exec jointo-server-app alembic upgrade head
4. 验证约束
SELECT conname, contype
FROM pg_constraint
WHERE conrelid = 'ai_prompts_system'::regclass;
结果:
conname | contype
---------------------------------------+---------
ai_prompts_system_name_version_unique | u -- ✅ 唯一约束
ai_prompts_system_pkey | p -- 主键
ai_prompts_system_prompt_type_check | c -- 检查约束
测试结果
运行 Repository 测试:
docker exec jointo-server-app pytest tests/unit/repositories/test_ai_prompt_system_repository.py -v
结果: ✅ 21 passed
所有测试通过,包括:
test_create_duplicate_name_version- 验证唯一约束正常工作- 其他 20 个测试 - 验证基本功能正常
影响
数据完整性
- ✅ 保证同一名称和版本的提示词只能存在一个
- ✅ 防止数据重复
- ✅ 符合需求文档设计
测试
- ✅ 所有 Repository 测试通过
- ✅ 唯一约束测试正常工作
相关文件
迁移文件:
server/alembic/versions/20260204_1626_410fc8822148_add_ai_prompts_system_name_version_.py
测试文件:
server/tests/unit/repositories/test_ai_prompt_system_repository.py
技术细节
约束定义
ALTER TABLE ai_prompts_system
ADD CONSTRAINT ai_prompts_system_name_version_unique
UNIQUE (name, version);
约束作用
- 同一个提示词名称可以有多个版本
- 但同一名称+版本的组合只能存在一次
- 例如:
- ✅ 允许:("剧本提示词", "1.0.0") 和 ("剧本提示词", "1.1.0")
- ❌ 禁止:两个 ("剧本提示词", "1.0.0")
后续建议
- 审查旧迁移文件: 检查
20260203_1521_9a6a8471bda0是否需要修复(虽然新迁移已解决问题) - 测试数据清理: 确保测试使用唯一的测试数据名称,避免冲突
- 迁移审查流程: 建立迁移文件审查机制,防止类似错误
符合规范
- ✅ UUID v7 主键(应用层生成)
- ✅ SMALLINT 枚举类型
- ✅ TIMESTAMPTZ 时间字段
- ✅ 无物理外键约束(应用层保证引用完整性)
- ✅ 唯一约束(数据库层保证数据完整性)