web-dev-qa-db-fra.com

Comment utiliser avg et sum dans la requête SQLAlchemy

J'essaie de renvoyer une ligne de totaux/moyennes de mon ensemble de données qui contient le SUM de certains champs et le AVG d'autres.

Je pourrais le faire en SQL via:

SELECT SUM(field1) as SumFld, AVG(field2) as AvgFld 
FROM Rating WHERE url=[url_string]

Ma tentative de traduire cela en SQLAlchemy est la suivante:

totals = Rating.query(func.avg(Rating.field2)).filter(Rating.url==url_string.netloc)

Mais c'est une erreur avec:

TypeError: 'BaseQuery' object is not callable
34
mal-wan

Vous devez utiliser quelque chose comme:

from sqlalchemy.sql import func
session.query(func.avg(Rating.field2).label('average')).filter(Rating.url==url_string.netloc)

Vous ne pouvez pas utiliser MyObject.query ici, car SqlAlchemy essaie de trouver un champ où placer le résultat de la fonction avg, et il échoue.

52
Aidin

Vous ne pouvez pas utiliser MyObject.query ici, car SqlAlchemy essaie de trouver un champ dans lequel placer le résultat de la fonction avg, et il échoue.

Ce n'est pas tout à fait vrai. func.avg(Rating.field2).label('average') renvoie un objet Column (le même type d'objet qui lui a été donné pour être précis). Vous pouvez donc l'utiliser avec le with_entities méthode de l'objet de requête.

Voici comment vous le feriez pour votre exemple:

Rating.query.with_entities(func.avg(Rating.field2).label('average')).filter(Rating.url == url_string.netloc)
46
Antoine Reversat