如何使用SQLAlchemy中关系上定义的order_by和contains_eager?

2024-04-20 02:45:52 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我们想要保持模型中定义的关系顺序,Zen of Joined Eager Loading文档建议使用contains_eager()

“如果我们只想在集合加载和排序时使用一个联接,我们可以使用contains_eager()选项,如下面将显式联接/语句路由到急切加载的集合中所述。”

但下面的例子似乎表现得不一样。我肯定错过了什么,但不确定是什么

class Parent(Base):
    __tablename__ = "parent"

    parent_id = Column(types.Integer, primary_key=True)
    name = Column(types.String(200), nullable=False)


class Child(Base):
    __tablename__ = "child"

    order = Column(types.Integer, default=0)
    name = Column(types.String(200))

    parent_id = Column(types.Integer, ForeignKey(Parent.parent_id))
    parent = relationship(
        Parent,
        backref=backref(
            "children",
            cascade="all,delete",
            order_by="Child.order",
        ),
    )
query = session.query(Parent).options(
    contains_eager(Parent.children)
).filter(Parent.parent_id == 99).filter(Child.name == "foo")

生成以下SQL:

SELECT parent.parent_id, parent.name,
       child.order, child.name,
FROM parent, child
WHERE parent.parent_id = 99 AND parent.name = 'foo'

出于某种原因

ORDER BY child.order

缺少,即使它是在relationship()中定义的。有什么提示吗

如果在查询时指定order_by,它可以正常工作,但我希望避免多次编写相同的排序条件


Tags: nameidchild定义排序ordercolumninteger
1条回答
网友
1楼 · 发布于 2024-04-20 02:45:52

文档是正确的,它指出了这样一个事实,即如果使用大多数开箱即用的加载方法,则查询会被修改,并且可能不是最优的

建议使用contains_eager,其中:

1)用户负责构造正确的查询(包括联接、筛选器、排序等)

2)通过使用contains_eager,用户提示SA指定的关系包含在查询中


急切地加载关系的方法是使用joinedload

q_joined = (
    session
    .query(Parent)
    .options(joinedload(Parent.children))
    .filter(Parent.parent_id == parent_id)
)

但在这种情况下不能应用这些附加过滤器

使用contains_eager可以执行以下操作:

q_manual = (
    session
    .query(Parent)
    .join(Child)  # MUST HAVE THIS
    .options(contains_eager(Parent.children))
    .filter(Parent.parent_id == 99)
    # .filter(Child.name == "foo")  # you can add this, but you are "tricking" SA into believing that only these 'Child' are part of the Parent.children relationship.
    .order_by(Parent.parent_id, Child.order)  # JUST ADD THIS to solve the ordering
)

相关问题 更多 >