2016-10-17 3 views
1

関係に参加しました: SQLAlchemyの:チェーン内の列によって順序I'vは、このようなモデルを得た私のアプリでは

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名を取得1つのLEFT OUTER JOINクエリに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の精神で行うことができますか?

答えて

1

私はあなたのサンプルで遊んで、追加ポイントとしてPostgreSQLを使用しました。

クエリはCオブジェクトのリストを返します。伝統的にSQLでは、取得する列のみを並べ替えることができます。関係はシーンの中で取り出されるので、私はそれらがなぜソートできるのか分からない。

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

私が見つけたもう一つの解決策は、ORDER_BY使用することです:あなたのリストが取得されたら、あなたは超高速のメモリでそれを並べ替えることができますので、明るい側では

は、それは、あなたのメモリ内の全階層が付属しています relationshipため parameter

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)) 

tc.name、tb_1.name、ta_1.name

BY ORDERこれは、あなたが望んでいたものに近いですが、A.name, B.name, C.nameためにそれを得るために、リストを逆にする必要があります。

P.S:参照用私の正確なクラス定義:私は働い1で作業していない提案を交換し

#!/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://[email protected]/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) 
+0

@vac。上記のコメントはもう適用されません。新しいコードがテストされました。 – Muposat

関連する問題