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

Ada*_*dam 5 python sqlalchemy python-3.x

我有一个Single Table Inheritancesqlalchemy 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"}
Run Code Online (Sandbox Code Playgroud)

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

我希望children当我查询a Parent(由于lazy=False)时查询的内容按列index而不是id列(这是默认值)排序。

我通过将以下内容添加"order_by": "index"Human类中来实现这一目标__mapper_args__,如下所示:

__mapper_args__ = {"polymorphic_on": type, "polymorphic_identity": "human", "order_by": "index"}
Run Code Online (Sandbox Code Playgroud)

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

我已经尝试过以下方法:

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

这两种方法都不起作用。

既然它已被弃用,我怎样才能达到与order_byin相同的效果?mapper()

Ada*_*dam 4

我在sqlalchemy 的 github上提出问题后得到了答案。我提出回应,以防其他人搜索这个问题并在这里找到它,而不是 sqlalchemy 的 github。

答案:

关系加载的集合的顺序由关系()和/或 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",
   )
Run Code Online (Sandbox Code Playgroud)

也就是说,这与 mapper.order_by 无关,尽管该属性具有您正在寻求的效果。如果您在“父”端尝试过“relationship->order_by”,那是错误的端,它会转到定义实际要订购的内容的位置,在本例中为 backref。