group.members
をソートするには、GroupMembership関連オブジェクトを読み込み中にソートできる人を持っている必要があります。これは結合で実現できます。 group.members
が最初にロードGroupMembershipオブジェクトにアクセスし、あなたの現在の構成では
、group.group_memberships
関係を満たし、かつ関連プロキシはGroupMembership.person
関係属性アクセスのように各人のためのSELECTが発生します。
代わりにあなたがPerson.last_name
によって並べ替え同じクエリにGroupMembershipsと人の両方をロードしたい:、あなたが代わりに後方参照Group.group_memberships
のスカラー関係属性GroupMembership.person
にorder_by='Person.last_name'
を定義する必要が
class GroupMembership(Model):
__tablename__ = 'group_memberships'
id = Column(Integer, primary_key=True)
person_id = Column(Integer, ForeignKey('persons.id'), nullable=False)
group_id = Column(Integer, ForeignKey('groups.id'), nullable=False)
person = relationship('Person',
backref=backref('group_memberships',
cascade='all, delete-orphan'),
lazy='joined', innerjoin=True,
order_by='Person.last_name')
group = relationship('Group', backref=backref('group_memberships',
cascade='all, delete-orphan'))
# Other stuff
ている可能性やるべき論理的なもののように思える。一方、order_by
は「これらのアイテムをロードするときに適用する順序を示す」ので、joined loadingを使用すると意味があります。あなたは多対1の参照に参加しているので、外部キーはNULL可能ではないため、内部結合を使用できます。代わりに与えられた定義に
:
In [5]: g = Group(name='The Group')
In [6]: session.add_all([GroupMembership(person=Person(last_name=str(i)), group=g)
...: for i in range(30, 20, -1)])
In [7]: session.commit()
In [8]: g.members
2017-06-29 09:17:37,652 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2017-06-29 09:17:37,653 INFO sqlalchemy.engine.base.Engine SELECT groups.id AS groups_id, groups.name AS groups_name
FROM groups
WHERE groups.id = ?
2017-06-29 09:17:37,653 INFO sqlalchemy.engine.base.Engine (1,)
2017-06-29 09:17:37,655 INFO sqlalchemy.engine.base.Engine SELECT group_memberships.id AS group_memberships_id, group_memberships.person_id AS group_memberships_person_id, group_memberships.group_id AS group_memberships_group_id, persons_1.id AS persons_1_id, persons_1.last_name AS persons_1_last_name
FROM group_memberships JOIN persons AS persons_1 ON persons_1.id = group_memberships.person_id
WHERE ? = group_memberships.group_id ORDER BY persons_1.last_name
2017-06-29 09:17:37,655 INFO sqlalchemy.engine.base.Engine (1,)
Out[8]: [<__main__.Person object at 0x7f8f014bdac8>, <__main__.Person object at 0x7f8f014bdba8>, <__main__.Person object at 0x7f8f014bdc88>, <__main__.Person object at 0x7f8f01ddc390>, <__main__.Person object at 0x7f8f01ddc048>, <__main__.Person object at 0x7f8f014bdd30>, <__main__.Person object at 0x7f8f014bde10>, <__main__.Person object at 0x7f8f014bdef0>, <__main__.Person object at 0x7f8f014bdfd0>, <__main__.Person object at 0x7f8f0143b0f0>]
In [9]: [p.last_name for p in _]
Out[9]: ['21', '22', '23', '24', '25', '26', '27', '28', '29', '30']
この解決策の欠点はperson
関係は常に熱心にロードされ、GroupMembershipsを照会するときに適用ORDER BYされていることである。
In [11]: session.query(GroupMembership).all()
2017-06-29 12:33:28,578 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2017-06-29 12:33:28,578 INFO sqlalchemy.engine.base.Engine SELECT group_memberships.id AS group_memberships_id, group_memberships.person_id AS group_memberships_person_id, group_memberships.group_id AS group_memberships_group_id, persons_1.id AS persons_1_id, persons_1.last_name AS persons_1_last_name
FROM group_memberships JOIN persons AS persons_1 ON persons_1.id = group_memberships.person_id ORDER BY persons_1.last_name
2017-06-29 12:33:28,578 INFO sqlalchemy.engine.base.Engine()
Out[11]:
...
あなたドンそれが参照側で定義されているように関係上の 'uselist = False'引数を必要としません。つまり、' GroupMembership'エンティティは 'Person'と' Group'を参照できます。あなたは1対1の関係でそれを使用します。 –
GroupMembershipオブジェクトを一般的に手作業で扱いたいのですか?つまり、GroupMembershipsだけをSELECT /クエリするのは一般的ですか? –