2016-07-20 39 views
3

我的模型上有一個column_property,它是輔助模型上關係的計數。從其父項中分離子查詢

membership_total = column_property(
     select([func.count(MembershipModel.id)]).where(
      MembershipModel.account_id == id).correlate_except(None)) 

這工作正常,直到我嘗試加入會員模型。

query = AccountModel.query.join(MembershipModel) 
# ProgrammingError: subquery uses ungrouped column "membership.account_id" from outer query 

我可以通過附加解決這個問題:

query = query.group_by(MembershipModel.account_id, AccountModel.id) 
# resolves the issue 

但我真的不希望這樣做。我希望它成爲自己的島嶼,它會忽略查詢所做的任何事情,並只專注於返回特定行帳戶ID的會員數。

我該怎麼做column_property,使其更健壯,更少依賴於父查詢正在做什麼?

回答

2

通過MembershipModelcorrelate_except()而不是None,如here在文檔中所述。如果當前方法可以與子查詢的封閉查詢相關聯,則允許省略子查詢的FROM子句中的所有內容。當您加入MembershipModel時,它將在封閉查詢中變得可用。

這是一個簡化的例子。鑑於2款AB

In [2]: class A(Base): 
    ...:  __tablename__ = 'a' 
    ...:  id = Column(Integer, primary_key=True, autoincrement=True) 
    ...:  

In [3]: class B(Base): 
    ...:  __tablename__ = 'b' 
    ...:  id = Column(Integer, primary_key=True, autoincrement=True) 
    ...:  a_id = Column(Integer, ForeignKey('a.id')) 
    ...:  a = relationship('A', backref='bs') 

和2所column_property定義上A

In [10]: A.b_count = column_property(
    select([func.count(B.id)]).where(B.a_id == A.id).correlate_except(B)) 

In [11]: A.b_count_wrong = column_property(
    select([func.count(B.id)]).where(B.a_id == A.id).correlate_except(None)) 

如果我們查詢只是A,一切都很好:

In [12]: print(session.query(A)) 
SELECT a.id AS a_id, (SELECT count(b.id) AS count_1 
FROM b 
WHERE b.a_id = a.id) AS anon_1, (SELECT count(b.id) AS count_2 
FROM b 
WHERE b.a_id = a.id) AS anon_2 
FROM a 

但是,如果我們加入B,第二個屬性錯誤地將B與封閉查詢相關聯完全省略FROM子句:

In [13]: print(session.query(A).join(B)) 
SELECT a.id AS a_id, (SELECT count(b.id) AS count_1 
FROM b 
WHERE b.a_id = a.id) AS anon_1, (SELECT count(b.id) AS count_2 
WHERE b.a_id = a.id) AS anon_2 
FROM a JOIN b ON a.id = b.a_id 
+0

謝謝!文檔也有確切的用例...:| –