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.3 KiB

SQLAlchemy 关系警告修复

日期: 2026-02-03
类型: 优化
影响范围: Screenplay 模型

问题描述

测试运行时出现 SQLAlchemy 关系警告:

SAWarning: relationship 'ScreenplayProp.tags' will copy column screenplay_props.prop_id 
to column screenplay_element_tags.element_id, which conflicts with relationship(s): 
'ScreenplayCharacter.tags', 'ScreenplayLocation.tags'

原因:多个 Screenplay 模型(Character、Location、Prop)都定义了 tags 关系,指向同一个 screenplay_element_tags 表,SQLAlchemy 检测到潜在的关系冲突。

解决方案

在每个模型的 sa_relationship_kwargs 中添加 overlaps="tags" 参数,告诉 SQLAlchemy 这是预期的重叠关系。

修改内容

1. ScreenplayCharacter 模型

文件: server/app/models/screenplay_character.py

tags: List["ScreenplayElementTag"] = Relationship(
    back_populates="character",
    sa_relationship_kwargs={
        "foreign_keys": "[ScreenplayElementTag.element_id]",
        "primaryjoin": "and_(ScreenplayCharacter.character_id==ScreenplayElementTag.element_id, ScreenplayElementTag.element_type==1)",
        "lazy": "selectin",
        "overlaps": "tags"  # ✅ 新增
    }
)

2. ScreenplayLocation 模型

文件: server/app/models/screenplay_location.py

tags: List["ScreenplayElementTag"] = Relationship(
    back_populates="location",
    sa_relationship_kwargs={
        "foreign_keys": "[ScreenplayElementTag.element_id]",
        "primaryjoin": "and_(ScreenplayLocation.location_id==ScreenplayElementTag.element_id, ScreenplayElementTag.element_type==2)",
        "lazy": "selectin",
        "overlaps": "tags"  # ✅ 新增
    }
)

3. ScreenplayProp 模型

文件: server/app/models/screenplay_prop.py

tags: List["ScreenplayElementTag"] = Relationship(
    back_populates="prop",
    sa_relationship_kwargs={
        "foreign_keys": "[ScreenplayElementTag.element_id]",
        "primaryjoin": "and_(ScreenplayProp.prop_id==ScreenplayElementTag.element_id, ScreenplayElementTag.element_type==3)",
        "lazy": "selectin",
        "overlaps": "tags"  # ✅ 新增
    }
)

验证结果

运行测试验证修复:

docker exec jointo-server-app pytest tests/integration/test_ai_integration.py -v

结果

  • 10 passed
  • ⏭️ 2 skipped
  • ⚠️ 0 warnings(SQLAlchemy 警告已消失)

技术说明

overlaps 参数的作用

overlaps 参数告诉 SQLAlchemy:

  1. 这些关系是有意设计的多态关联
  2. 不同模型可以共享相同的关系名称
  3. 通过 element_type 字段区分不同的关系

为什么需要这个参数

在多态关联设计中:

  • screenplay_element_tags.element_id 可以指向不同的表(character、location、prop)
  • 每个表都有一个 tags 关系
  • SQLAlchemy 默认会警告这种"冲突"
  • 添加 overlaps 参数明确告诉 SQLAlchemy 这是预期行为

相关文档

影响评估

  • 无功能影响
  • 无性能影响
  • 仅消除警告信息
  • 提升代码质量