2016-03-08 87 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