通过加盟连锁关系列订单

问题描述 投票:1回答:1

在我的应用我有这样的模型:

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的精神呢?

python sqlalchemy sql-order-by relation
1个回答
2
投票

我与样品发挥各地和使用的PostgreSQL的加了分。

您的查询返回C对象的列表,并在传统的SQL,你只能按列排序,您检索。该关系的幕后检索到的,所以我不明白为什么它应该有可能由他们来进行排序。

在光明的一面,一旦你的清单中查找它与在你的记忆整个层次,这样你就可以在内存超快速对其进行排序:

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

我发现另一种解决方案是使用ORDER_BY parameterrelationship

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)
© www.soinside.com 2019 - 2024. All rights reserved.