SQLAlchemy - 过滤子查询负载

SQLAlchemy - Filter on Subqueryload

假设以下模型,如何通过 subqueryload 加载与订单关联的货物,并根据 is_refunded 的状态进行过滤?

class Order(db.Model):
    id = db.Column(db.Integer, primary_key=True)

class Shipment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    shipment = db.Column(MutableDict.as_mutable(JSONB))
    is_refunded = db.Column(db.Boolean, server_default="false")
    order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
    order = db.relationship('Order', backref='shipments')

我希望得到以下几行内容,但这不是有效的语法:

orders = db.session.query(Order).options(
    db.subqueryload(Order.shipments).filter(Shipment.is_refunded==False))

一些背景:

如果需要任何说明,请告诉我。

提前致谢。

有趣的是,我一直想知道一种简单的 "options" 方法来做这种事情,所以上面的语法很有趣。

但是,目前,通过 relationship() 设置的属性契约是它们仅直接使用在 relationship() 中设置的条件。没有简单的方法可以在运行时更改标准,同时仍然使用提供的加载程序服务。

直接使用具有自定义条件的加载程序服务的两个选项是使用连接写出查询,然后与 contains_eager 组合(适用于连接加载,而不是真正的子查询加载),或者使用满足您正在寻找的标准(您将通过 primaryjoin 建立)的新 relationship()。

subqueryload 存在另一个选项,即自己发出相同的查询但实际上不使用 subqueryload 选项。这里的特殊技术是能够用查询结果填充集合,这样它们就不会被记录为更改事件。 set_committed_value function is used for this, and an example which illustrates the "original" form of subqueryload (before it was built in) illustrates this, over at DisjointEagerLoading。对于绝大多数简单情况,针对固定实体滚动你自己的 "subqueryload" 并不是很难,该技术在该示例中得到了说明。