如何替换 SQLAlchemy 映射器已弃用的“order_by”选项?

问题描述

我有一个 Single Table Inheritance sqlalchemy orm 模型,如下所示:

class Human(Base):
    
    __tablename__ = "human"

    id = Column(Integer,primary_key=True)
    name = Column(String)
    index = Column(Integer)
    parent_id = Column(Integer,ForeignKey("human.id"),nullable=True)
    type = Column(String)
    parent = relationship(
        "Human",cascade="save-update,merge",backref=backref("children",cascade="all"),lazy=False,remote_side="Human.id",)

    __mapper_args__ = {"polymorphic_on": type,"polymorphic_identity": "human"}

class Parent(Human):

    __mapper_args__ = {"polymorphic_identity": "parent"}

class Child(Human):

    hobby = Column(String)
    pet = Column(String)

    __mapper_args__ = {"polymorphic_identity": "child"}

这种关系看起来像一个嵌套的树,我可以在其中查询最年长的人(即:曾祖父母,使用 query.get(1)),然后在他的 children 属性中,他的所有 children 将是礼物,每个孩子也会有他们的 children 礼物。 这种关系在各个方面都很好。

我希望查询 children查询Parent(由于 lazy=False)按 index 列而不是 id 列排序(这是认值)。

我是通过将以下 "order_by": "index" 添加Human 类的 __mapper_args__ 来实现的,如下所示:

__mapper_args__ = {"polymorphic_on": type,"polymorphic_identity": "human","order_by": "index"}

我最近发现在 sqlAlchemy 中,order_by 类中的 mapper() 参数自 sqlAlchemy 版本 1.1 (reference) 以来已被弃用。并且他们说使用 Query.order_by() 来订购套装,但由于某种原因这对我不起作用。

我尝试了以下方法

  • order_by 添加查询中,session.query(Human).order_by(Human.index).get(1)
  • order_by="Human.index" 添加relationship() 类中的 Human

这两种方法都行不通。

既然order_by 中的mapper() 已被弃用,我如何才能获得与它相同的效果

解决方法

我在 sqlalchemy's github 上提出问题后得到了答案。 如果其他人搜索此问题并在此处而不是 sqlalchemy 的 github 中找到它,我将给出响应。

The answer:

由关系加载的集合的排序由关系()和/或 backref 的 order_by 参数控制。在这种情况下,您希望对“子项”进行排序,因此将其放在定义“子项”的位置:

parent = relationship(
       "Human",cascade="save-update,merge",backref=backref("children",cascade="all",order_by="Human.index"),lazy=False,remote_side="Human.id",)

也就是说,这与 mapper.order_by 无关,尽管该属性具有您想要的效果。如果您在“父”端尝试过关系->order_by,那是错误的一面,它会转到定义要订购的实际事物的地方,在这种情况下是 backref。