在我的应用我有这样的模型:
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()
它正常工作 - 我得到的所有的C名称与它的B和在一个LEFT OUTER的名称JOIN查询。
但我不知道如何通过这个查询与订购: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)