Opened 10 years ago
Closed 10 years ago
#23669 closed Bug (fixed)
ProgrammingError when aggregating over an annotated & grouped ORM query
Reported by: | Gregory Goltsov | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.6 |
Severity: | Normal | Keywords: | orm, annotate, aggregate, values, avg, max |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I have a simplified Django model:
class Module(models.Model): score = models.IntegerField() user = models.ForeignKey(User)
I was trying to construct a query to get the average highest score per module per user. In SQL, the query would look something like:
SELECT m.id AVG(max_score) FROM ( SELECT m.id Max(m.score) AS max_score FROM module m GROUP BY m.user_id, m.id ) f GROUP BY m.id
In Django ORM the query looks like:
Module.objects.values( # GROUP BY module_id, user_id 'id', 'user' ).annotate( # adding MAX(score) to the SELECT clause max_score=Max('score') ).aggregate( # actually getting the average Avg('max_score') )
This case is even documented in the docs: https://docs.djangoproject.com/en/1.6/topics/db/aggregation/#aggregating-annotations
However, upon evaluating, I encounter the following ProgrammingError:
ProgrammingError: syntax error at or near "FROM" LINE 1: SELECT FROM (SELECT
The ORM query looks like a perfectly normal query, no hacking, so I was really surprised to see this behaviour. Furthermore, I'm not the only one having this issue, dating as far as 2010:
Change History (5)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
Description: | modified (diff) |
---|
comment:3 by , 10 years ago
I can't replicate this issue with Django 1.7. I do remember running into this about a year ago and I seem to remember it being fixed already. Which version of Django are you using?
comment:4 by , 10 years ago
I suspect you simplified the code too much -- since m.id
is a primary key, there can only be one score
value per id
value; max(score)
makes little sense.
More generally, you may note that the documentation example you linked to aggregates over sub-records, and you are trying to aggregate over the main record -- which, again, makes little sense when used via annotate
rather than aggregate
.
I have a strong suspicion that the hack mentioned will break "normal" annotate()
calls (aggregating over sub-records).
comment:5 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I can reproduce the reported issue in 1.6 but it's fixed in 1.7.
I traced the fix back to 4bd55547214ae149acadffe60536c379d51e318f.
Interestingly enough, in one of the questions someone hacked
django.db.models.sql.query.BaseQuery
internals to make the query work: it's in the Hacking Django section of the question from https://stackoverflow.com/questions/2558992/programmingerror-when-aggregating-over-an-annotated-grouped-django-orm-query