2016-03-08 89 views
0

试图(和失败)来包装我围绕着如何在下列情况下使用SQLAlchemy头SQLAlchemy的预先加载:有关系

假设我有一个数据库,即:

A has a (one -> many) relationship to B 

B has a (one -> many) relation to C 

如果我想遍历所有B的给定A,我可以这样做:

for b in a.bs: 
    print "hello" 

如果我要遍历所有的C的间接属于A,我可以这样做:

for b in a.bs: 
    for c in b.cs: 
     print "hello" 

但是,我知道最外层循环的每次迭代都会执行新的SQL查询。

我的,我可以用subqueryload来防止这种情况的发生做了了解:

for b in session.query(b).options(subqueryload(B.c)).filter_by(B.a_id == a.id): 
    for c in b.cs: 
     print "hello" 

那是最整洁的方式做到这一点?

是不是有些语法让我从实际的'a'对象开始。也许是这样的:

for b in a.bs.options(subqueryload(B.c)): 
    ... 

很多感谢您的帮助

回答

0

可以subqueryload任意联接路径是这样的:

session.query(A).options(subqueryload(A.b).subqueryload(B.c)) 

这使用三个查询和将加载A.bB.c对于A.b中的每个B

+0

感谢您的支持。如果我只想要与我的对象“a”间接相关的行,那么我必须在上面的回答中正确地执行一个过滤器吗? 如果是这种情况,我无法直接从'a'对象上的关系属性进行查询。如:a.bs.options(...我希望这是有道理的 – maambmb

+0

@mambmb哦,我想我误解了你的原始问题如果你只有一个'A'对象,并且你想用'Bc'来得到'Ab''在每个'B'中加载,你可以选择按照上面所述做过滤器,或者在你首先查询那个'A'对象时做一个链接子查询(如我的答案)*。如果你想要' aboptions',你必须将'Ab'配置为'lazy =“dynamic”',这使得'Ab'返回一个'Query'而不是一个列表,这个列表有其优缺点 – univerio

+0

非常感谢你清除我非常感激! – maambmb