问题描述
我有一个 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 中找到它,我将给出响应。
由关系加载的集合的排序由关系()和/或 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。