2010-05-29 45 views
4

我有一个wiki数据库布局,其中PageRevisions。每个版本都有一个page_id引用页面,与引用页面的关系为page;每个页面与其所有修订版本具有all_revisions关系。迄今为止很常见。SQLAlchemy - 关系不仅限于外键

但是我想为这些页面实现不同的时代:如果一个页面被删除并被重新创建,新的修订版本会有一个新的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:无法确定primaryjoin条件关系的方向.. ',我试过了所有我想到的,它没有奏效。

我在做什么错?这是做这件事的坏方法吗?除了关系之外,怎么做呢?

两个类后

回答

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, 
    ) 
+0

Thanks!那样做了。我没有让所有的东西在真正的应用程序中工作,但它在小演示中起作用,所以至少现在可以解决这个特定的问题。 @BTW:啊,忘记了,因为我们有一个特殊的init方法来自动添加。 [已更新,工作代码](http://paste.pocoo.org/show/220827/)。 – Marian 2010-06-01 20:39:25

+0

任何想法为什么添加它后修复?我认为字符串符号是为了避免这样的东西? (并且,如果两个类都创建后,它何时评估这些字符串?) – Marian 2010-06-01 21:34:08

+1

我已经在字符串中添加了正确表达式的解释和示例。 – 2010-06-02 08:31:33