SQLAlchemy - 关系不仅限于外键

时间:2010-05-29 15:22:03

标签: python sqlalchemy relationship database

我有一个带有PageRevisions的wiki数据库布局。每个版本都有page_id引用页面,与引用页面的page关系;每个页面与其所有修订版本都有all_revisions个关系。到目前为止很常见。

但是我想为页面实现不同的时期:如果页面被删除并重新创建,则新版本会有一个新的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']
)

Full code(你可以按原样运行)

然而,这总是引发 ArgumentError:无法确定主要条件的关系方向......“,我已经尝试了所有我想到的,它没有用。

我做错了什么?对于这样做,这是一种不好的方法吗?除了关系之外,它怎么能做到呢?

1 个答案:

答案 0 :(得分: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参数不是字符串,因此it's not evaluated。在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,
    )