如何找到比带有子项的最后一个实体更近的实体集

时间:2010-11-15 20:02:33

标签: python orm sqlalchemy

我指定了两个SQLAlchemy模型对象:

class SpecInstance(Base):
    spec_id = Column(Integer, ForeignKey('spec.spec_id'))
    details = Column(String)

class Spec(Base):
    spec_id = Column(Integer)
    spec_date = Column(DateTime)
    instances = relationship(SpecInstance, backref="spec", cascade="all, delete, delete-orphan")

我正在寻找一个查询,它只返回那些spec_date大于最新版本的Spec个对象。例如,给定的对象如下:

Spec(spec_id=1, spec_date='2010-10-01')
Spec(spec_id=2, spec_date='2010-10-02')
Spec(spec_id=3, spec_date='2010-10-03')

SpecInstance(spec_id=2, details='whatever')

我希望我的查询仅返回规范3.规范2不合格,因为它有实例。规范1不合格,因为它比规范2旧。

我该怎么做?

1 个答案:

答案 0 :(得分:0)

我没有测试这段代码,因为我很确定它会起作用,设置env是一种开销。

在纯SQL中,可以使用子查询执行此操作。在sqlalchemy中,子查询以这种方式创建:

sq = session.query(Spec.spec_date.label('most_recent'))\
            .join((SpecInstance, SpecInstance.spec_id==Spec.spec_id))\
            .order_by(desc(Spec.spec_date))\
            .limit(1).subquery()

在这里,我们加入了两个表,所以只考虑Spec with SpecInstances,然后我们按日期排序,所以最新的是在顶部,并且只采用第一个 - 最年轻的实例 - 我们只需要它日期。这将不会被执行 - 它将作为子查询准备在:

session.query(Spec)\
       .join((sq, Spec.spec_date>sq.c.most_recent))

这非常简单。注意在连接构造上加上双括号,并在sq的第二个查询中包含.c,因为'most_recent'将是动态列查找。