【问题标题】:SQLAlchemy query filter on child attribute子属性的 SQLAlchemy 查询过滤器
【发布时间】:2017-03-24 07:30:28
【问题描述】:

我的模型由一对一关系的 Parent 和 Child 组成:

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 对象。

【问题讨论】:

    标签: python orm sqlalchemy one-to-one


    【解决方案1】:

    您应该更改您的查询。

    # 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))
    

    【讨论】:

    • 感谢@van,但我正在尝试为 get_fundamentals 复制 Quantopian API,另请参阅此问题:stackoverflow.com/questions/40497528/…。我无法理解他们是如何定义底层模型的。
    • 我将您的问题解读为 我如何获得Parent 对象? 我相信我的回答涵盖了它。至于您的另一个问题及其与 Quantopian 的链接:问题尚不清楚 - 什么有效,什么无效?我只能确认使用多级属性导航(例如Parent.child[.subchild].property)访问关系不适用于 sqlalchemy。而 Quantopian 的示例并没有显示任何与此相反的内容 - fundamentals 是模块,而不是映射类。
    • 是的@van,你完全正确。我只是想指出我的另一个问题,它起源于这个问题,你给了我一个很好的提示。现在我也认为基础必须是模块。
    【解决方案2】:

    我知道你提到你不想查询子类,但因为那是幕后发生的事情(SQLAlchemy 只是对你隐藏它),你也可以这样做。然后您可以简单地通过 backref 访问父对象。由于您指定了lazy=joined,因此速度将完全相同。

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

    【讨论】:

      猜你喜欢
      • 2015-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 2014-04-18
      • 1970-01-01
      • 2021-08-10
      • 1970-01-01
      相关资源
      最近更新 更多