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
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:
- 这些关系是有意设计的多态关联
- 不同模型可以共享相同的关系名称
- 通过
element_type字段区分不同的关系
为什么需要这个参数
在多态关联设计中:
screenplay_element_tags.element_id可以指向不同的表(character、location、prop)- 每个表都有一个
tags关系 - SQLAlchemy 默认会警告这种"冲突"
- 添加
overlaps参数明确告诉 SQLAlchemy 这是预期行为
相关文档
影响评估
- ✅ 无功能影响
- ✅ 无性能影响
- ✅ 仅消除警告信息
- ✅ 提升代码质量