ORM を使用した count、group_by、order_by による SQLAlchemy
-
21-08-2019 - |
質問
count()、group_by、order_by を使用して 1 対多の結合を行う必要がある関数がいくつかあります。sqlalchemy.select 関数を使用して ID のセットを返すクエリを作成し、それを反復して個々のレコードに対して ORM 選択を実行します。私が疑問に思っているのは、反復を行わなくても済むように、単一のクエリで ORM を使用して必要なことを実行する方法があるかどうかです。
これが私が今やっていることの一例です。この場合、エンティティは場所とガイドであり、1 対多にマッピングされます。関連するガイドの数によって並べ替えられた上位の場所のリストを取得しようとしています。
def popular_world_cities(self):
query = select([locations.c.id, func.count(Guide.location_id).label('count')],
from_obj=[locations, guides],
whereclause="guides.location_id = locations.id AND (locations.type = 'city' OR locations.type = 'custom')",
group_by=[Location.id],
order_by='count desc',
limit=10)
return map(lambda x: meta.Session.query(Location).filter_by(id=x[0]).first(), meta.engine.execute(query).fetchall())
解決
これを行うための最良の方法を見つけました。単に供給するだけです from_statement
の代わりに filter_by
またはそのようなもの。そのようです:
meta.Session.query(Location).from_statement(query).all()
解決 3
これを行うための最良の方法を見つけました。単に供給するだけです from_statement
の代わりに filter_by
またはそのようなもの。そのようです:
meta.Session.query(Location).from_statement(query).all()
他のヒント
あなたがやろうとしていることは、[現在の選択呼び出しから作成された] サブクエリとテーブルの間の SQLAlchemy 結合に直接マッピングされます。順序を副選択の外に移動し、count(desc) を含む別のラベル付き列を作成するとよいでしょう。その列によって外部選択を順序付けします。
それ以外には、自明ではないものはあまり見当たりません。
私はこれを見つけるのが大変でしたが、SQLAlchemy はサポートしています group_by
. 。Query のドキュメントにはそのようには記載されていませんが、サポートされています。私はそれを使用しました。
そして、次のこともできます order_by
. 。あなたと同じように特別なクラス/クエリを作成しようとしましたが、あることがわかりました group_by()
関数。