Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use avg and sum in SQLAlchemy query

I'm trying to return a totals/averages row from my dataset which contains the SUM of certain fields and the AVG of others.

I could do this in SQL via:

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

My attempt to translate this into SQLAlchemy is as follows:

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

But this is erroring out with:

TypeError: 'BaseQuery' object is not callable 
like image 273
mal-wan Avatar asked Aug 22 '11 04:08

mal-wan


People also ask

How do you sum in SQLAlchemy?

We first extract the average value of the percentage column using SQLalchemy's `func. avg()` function. Then we use the `func. sum()` function to get the sum of the values in the percentage column.

How does the querying work with SQLAlchemy?

All SELECT statements generated by SQLAlchemy ORM are constructed by Query object. It provides a generative interface, hence successive calls return a new Query object, a copy of the former with additional criteria and options associated with it.

How do I query data in a SQLAlchemy Flask?

Querying Records For this purpose Flask-SQLAlchemy provides a query attribute on your Model class. When you access it you will get back a new query object over all records. You can then use methods like filter() to filter the records before you fire the select with all() or first() .

What is all () in SQLAlchemy?

method sqlalchemy.orm.Query. all() Return the results represented by this Query as a list. This results in an execution of the underlying SQL statement. The Query object, when asked to return either a sequence or iterator that consists of full ORM-mapped entities, will deduplicate entries based on primary key.


2 Answers

You should use something like:

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

You cannot use MyObject.query here, because SqlAlchemy tries to find a field to put result of avg function to, and it fails.

like image 70
Aidin Avatar answered Oct 13 '22 01:10

Aidin


You cannot use MyObject.query here, because SqlAlchemy tries to find a field to put result of avg function to, and it fails.

This isn't exactly true. func.avg(Rating.field2).label('average') returns a Column object (the same type object that it was given to be precise). So you can use it with the with_entities method of the query object.

This is how you would do it for your example:

Rating.query.with_entities(func.avg(Rating.field2).label('average')).filter(Rating.url == url_string.netloc) 
like image 31
Antoine Reversat Avatar answered Oct 12 '22 23:10

Antoine Reversat