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

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")

后续建议

  1. 审查旧迁移文件: 检查 20260203_1521_9a6a8471bda0 是否需要修复(虽然新迁移已解决问题)
  2. 测试数据清理: 确保测试使用唯一的测试数据名称,避免冲突
  3. 迁移审查流程: 建立迁移文件审查机制,防止类似错误

符合规范

  • UUID v7 主键(应用层生成)
  • SMALLINT 枚举类型
  • TIMESTAMPTZ 时间字段
  • 无物理外键约束(应用层保证引用完整性)
  • 唯一约束(数据库层保证数据完整性)