gpt4 book ai didi

python - 按链式连接关系中的列排序

转载 作者:行者123 更新时间:2023-12-01 03:38:04 25 4
gpt4 key购买 nike

在我的应用程序中,我有这样的模型:

class A(Base):
id = Column(UUID, primary_key=True)
name_a = Column(Text)

class B(Base):
id = Column(UUID, primary_key=True)
name_b = Column(Text)
parent_a_id = Column(UUID, ForeignKey(A.id))
parent_a = relationship(A, lazy='joined')

class C(Base):
id = Column(UUID, primary_key=True)
name_c = Column(Text)
parent_b_id = Column(UUID, ForeignKey(B.id))
parent_b = relationship(B, lazy='joined')

当我这样做时:

DBSession().query(C).all()

它工作正常 - 我在一个 LEFT OUTER JOIN 查询中获得了所有 C 名称及其 B 和 A 名称。

但我想知道如何使用以下查询排序:name_a、name_b、name_c

我正在尝试做类似的事情:

DBSession().query(C).order_by(
C.parent_b.parent_a.name_a,
C.parent_b.name_b,
C.name_c
).all()

这样的代码不起作用。如何使用 sqlalchemy 精神来完成它?

最佳答案

我尝试了你的示例并使用 PostgreSQL 来添加点。

您的查询返回 C 对象列表,传统上在 SQL 中您只能按检索的列进行排序。这些关系是在幕后检索的,所以我不明白为什么可以按它们进行排序。

好的一面是,一旦您的列表被检索,它就会在您的内存中附带整个层次结构,因此您可以在内存中超快速地对其进行排序:

clist = session.query(C).all()
sorted(clist, key=lambda c:(c.b.a.name, c.b.name, c.name))

我发现的另一个解决方案是使用 order_by parameter 来表示 relationship:

class B(Base):
...
a = relationship(A, order_by="A.name", lazy='joined')

class C(Base):
...
b = relationship(B, order_by="B.name", lazy='joined')

最终结果:

print (session.query(C).order_by(C.name) )

ORDER BY tc.name, tb_1.name, ta_1.name

这与您想要的很接近,但您需要反转列表才能按 A.name、B.name、C.name 顺序获得它。

P.S.:我的确切类定义供引用:

#!/usr/bin/env python
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, ForeignKey, create_engine, Text
from sqlalchemy.orm import relationship

engine_connect_str = "postgresql://postgres@MYSERV/mydb"
engine = create_engine(engine_connect_str, echo=False)
Session = sessionmaker(engine)
session = Session()
Base = declarative_base()


class A(Base):
__tablename__ = 'ta'
id = Column('id', Integer, primary_key=True)
name = Column(Text)

def __repr__(self):
return "{}(id={}, name='{}')".format(self.__class__.__name__, self.id, self.name)

class B(Base):
__tablename__ = 'tb'
id = Column('id', Integer,primary_key=True)
name = Column(Text)
a_id = Column('aid', ForeignKey(A.id), nullable=False)

a = relationship(A, order_by="A.name", lazy='joined')

def __repr__(self):
return "{}(id={}, name='{}', a_id={})".format(self.__class__.__name__, self.id, self.name, self.a_id)

class C(Base):
__tablename__ = 'tc'
id = Column('id', Integer, primary_key=True)
name = Column(Text)
b_id = Column('bid', ForeignKey(B.id), nullable=False)

b = relationship(B, order_by="B.name", lazy='joined')

def __repr__(self):
return "{}(id={}, name='{}', b_id={})".format(self.__class__.__name__, self.id, self.name, self.b_id)

关于python - 按链式连接关系中的列排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40095933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com