2016-11-10 66 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