0

私はこのように見える3つのモデルを持っています(簡略化):

ユーザー:

id
username

リソース:

id
name
description

コメント:

id
user_id (relationship User)
resource_id (relationship Resource)
data
date_created

ユーザーのコメントをクエリして、リソースごとにグループ化しようとしています。結果を次のように戻したい:[(Resource A、[Comment、Comment、Comment、...])、(Resource B、[Comment、Comment、...])、(Resource X、[Comment ])]

私はこれを構築するためのさまざまな方法を試しましたが、私はそれを理解できないようです。このようなことをするための適切な方法は何でしょうか?

編集

現在、コードは次のようになっています。

contrib = db_session.query(Resource).filter(Comment.user==user, Resource.uuid==Comment.resource_id).distinct(Comment.resource_id).order_by(desc(Comment.date_created))
comments = db_session.query(Comment, Resource).filter(Comment.user==user, Comment.resource_id.in_([r.uuid for r in contrib]), Resource.uuid==Comment.resource_id).order_by(desc(Comment.date_created))

次に、リスト/辞書の理解を使用して、これらの結果を次のようなものに結合します

[{resource: Resource, comments:[Comment, Comment, Comment]}, {resource: Resource, comments:[Comment, .....]}, .....]

これを行うためのより良い方法がなければなりません!

4

2 に答える 2

1

カスタムMappedCollectionを使用してコメントをグループ化できます。

from sqlalchemy.orm.collections import collection, MappedCollection

class GroupedCollection(MappedCollection):

  def __init__(self):
    super(GroupedCollection, self).__init__(
      self,
      lambda e: e.resource_id # the key we want to group by
    )

  @collection.internally_instrumented
  def __setitem__(self, key, value, _sa_initiator=None):
    if key in self:
      # there is already another comment for that resource
      # we simply append the comment (or you could do something
      # more fancy here if you would like to order the comments)
      self[key]['comments'].append(value)
    else:
      # we create a new entry with a dictionary containing the
      # resource and comment
      super(GroupedCollection, self).__setitem__(
        key,
        {'resource': value.resource, 'comments': [value]},
        _sa_initiator
      )

次に、対応する関係をUserクラスに追加します。

class User(Base):

  # ...

  grouped_comments = relationship(
    'Comment',
    collection_class=GroupedCollection
  )

アクセスすると、リソースごとにグループ化されたコメントが表示されます。

>>> user.grouped_comments
{
  'resource_id_1': {'resource': <Resource 1>, 'comments': [<Comment ...>, <Comment ...>]},
  'resource_id_2': {'resource': <Resource 2>, 'comments': [<Comment ...>]}
}
>>> user.grouped_comments.values()
[
  {'resource': <Resource 1>, 'comments': [<Comment ...>, <Comment ...>]},
  {'resource': <Resource 2>, 'comments': [<Comment ...>]}
]

この関係は、関連するモデルを表示するためにのみ使用する必要があることに注意してください。モデルの追加/削除を有効にするには、追加の作業が必要になります。

最後に、これを再現したいパターンであればGroupedCollection、グループ化キーを指定できるファクトリ関数を簡単に作成できます。

于 2013-02-19T04:54:31.727 に答える
0

デモを確認してください:http ://sqlfiddle.com/#!2/9f2ea/2

お役に立てれば

于 2013-02-18T16:36:11.353 に答える