SQLAlchemy - 关系不仅限于外键
我有一个维基数据库的结构,里面有两个主要部分:Page
(页面)和Revisions
(修订)。每个修订都有一个page_id
,它指向对应的页面,还有一个page
的关系,表示它关联的页面;每个页面都有一个all_revisions
的关系,包含了所有的修订。到这里都很常见。
但我想为页面实现不同的“时代”(epoch):如果一个页面被删除后又重新创建,那么新的修订就会有一个新的epoch
。为了帮助找到正确的修订,每个页面都有一个current_epoch
字段。现在我想在页面上提供一个revisions
的关系,只包含那些与当前时代匹配的修订。
这是我尝试过的:
revisions = relationship('Revision',
primaryjoin = and_(
'Page.id == Revision.page_id',
'Page.current_epoch == Revision.epoch',
),
foreign_keys=['Page.id', 'Page.current_epoch']
)
完整代码(你可以直接运行这个代码)
然而,这总是引发ArgumentError: Could not determine relationship direction for primaryjoin condition ...`的错误,我尝试了所有想到的方法,但都没有成功。
我哪里做错了?这样做是不是不太好?除了用关系,还有什么其他方法可以实现这个功能?
1 个回答
4
试着在创建完两个类之后再安装关系:
Page.revisions = relationship(
'Revision',
primaryjoin = (Page.id==Revision.page_id) & \
(Page.current_epoch==Revision.epoch),
foreign_keys=[Page.id, Page.current_epoch],
uselist=True,
)
顺便说一下,你的测试不太正确:revisions
属性是从数据库加载数据的,但你还没有把它们添加到会话中。
更新:你代码中的问题是 primaryjoin
参数不是字符串,所以它没有被评估。使用字符串作为 primaryjoin
是可以正常工作的:
class Page(Base):
# [skipped]
revisions = relationship(
'Revision',
primaryjoin = '(Page.id==Revision.page_id) & '\
'(Page.current_epoch==Revision.epoch)',
foreign_keys=[id, current_epoch],
uselist=True,
)