2016-11-10 95 views
2

我的模型由父母和子女有一個一對一的關係:SQLAlchery查詢篩選器屬性

class Parent(Base): 
    __tablename__ = 'parent' 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    child = relationship("Child", backref="parent", uselist=False, lazy='joined') 


class Child(Base): 
    __tablename__ = 'child' 
    child_id = Column(Integer, ForeignKey(Parent.id), primary_key=True) 
    value = Column(Integer) 

我的測試數據如下:

q = s.query(Parent) 
pd.read_sql(q.statement,s.bind) 
    id name child_id value 
    1  a   1  10 
    2  b   2  20 
    3  c   3  30 

現在的我ð喜歡使用此查詢與child.value> 20只得到家長:

q = s.query(Parent).filter(Parent.child.value > 20) 

,但出現此錯誤:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object 
associated with Parent.child has an attribute 'value' 

當然,我可以直接查詢Child類,但我的目標是檢索一個Parent對象。

回答

4

你應該改變你的查詢。

# version-1: use JOIN 
q = s.query(Parent).join(Child, Parent.child).filter(Child.value > 20) 

# or: 
# version-2: use EXISTS 
q = s.query(Parent).filter(Parent.child.has(Child.value > 20)) 
+0

感謝@van但我試圖複製爲get_fundamentals的Quantopian API,也看到了這個問題:http://stackoverflow.com/questions/40497528/sqlalchemy-model-for-quantopian-get-fundamentals 。我無法理解他們是如何定義底層模型的。 – kostia

+0

我把你的問題看成是*我怎樣才能得到'Parent'對象?*並且我相信我的答案涵蓋了它。 至於你的其他問題和它與Quantopian的聯繫:問題不清楚 - 什麼可行,什麼不可行? 我只能確認使用多級屬性導航(如'Parent.child [.subchild] .property')訪問關係不適用於sqlalchemy。而Quantopian的例子並沒有顯示任何與之相反的東西 - 「基礎」是模塊,而不是映射類。 – van

+0

是@van,你完全正確。我只是想指出我的另一個問題,這個問題來自這個問題,你給了我一個很好的提示。現在我也認爲基本面必須是模塊。 – kostia

0

我知道你提到你不想查詢的子類,但因爲這是發生了什麼幕後(SQLAlchemy的只是你隱藏了它),你還不如。然後你可以簡單地通過backref訪問父對象。自從您指定lazy = joined後,速度將完全相同。

q = s.query(Child).filter(Child.value > 20) 
parent_obj = q.parent