J'ai plusieurs fonctions où j'ai besoin de faire une jointure de type one-to-many, en utilisant count(), group_by et order_by. J'utilise la fonction sqlalchemy.select pour produire une requête qui me renverra un ensemble d'identifiants, que je parcours ensuite pour effectuer une sélection ORM sur les enregistrements individuels. Ce que je me demande, c'est s'il existe un moyen de faire ce dont j'ai besoin en utilisant l'ORM dans une seule requête afin d'éviter d'avoir à faire la itération.
Voici un exemple de ce que je fais actuellement. Dans ce cas, les entités sont Location et Guide, avec une relation one-to-many. J'essaie de obtenir une liste des principales locations triées par le nombre de guides auxquels elles sont liées.
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())
Solution
J'ai trouvé la meilleure façon de faire cela. Il suffit de fournir une from_statement
au lieu d'un filter_by
ou quelque chose du genre. Comme ceci:
meta.Session.query(Location).from_statement(query).all()