#28395 closed Cleanup/optimization (fixed)
first() adds id field to group by clause on aggregation queries
Reported by: | John Gresty | Owned by: | Botond Béres |
---|---|---|---|
Component: | Documentation | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Botond Béres | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
When evaluating an aggregation query, for example:
MyModel.objects.values('group').annotate(value=Sum('value'))
works as expected. However adding first()
to the end will add the id field into the resulting queryset and as such the annotated value will be the value of the first row, instead of the sum of the group.
>>> MyModel.objects.create(value=10) <MyModel: MyModel object> >>> MyModel.objects.create(value=20) <MyModel: MyModel object> >>> MyModel.objects.values('group').annotate(value=Sum('value')) <QuerySet [{'group': 0, 'value': 30}]> >>> MyModel.objects.values('group').annotate(value=Sum('value')).first() {'group': 0, 'value': 10}
Change History (5)
comment:1 by , 7 years ago
Component: | Database layer (models, ORM) → Documentation |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | Bug → Cleanup/optimization |
Version: | 1.11 → master |
comment:2 by , 7 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:3 by , 7 years ago
Has patch: | set |
---|
I've added a small patch that links from the first() definition to the aggregation section which mentions interaction with default ordering
Version 0, edited 7 years ago by (next)
Note:
See TracTickets
for help on using tickets.
The
first()
method requires an ordering to be specified else it would return non-deterministic results hence why it's usingorder_by('pk')
when the queryset isn't ordered.This is a bit similar to #10574 except the implicit ordering is added by
first()
and not_meta.ordering
so I'd suggest we link to the aggregation section mentioning interaction with default ordering or adjust the documention to account for that.IMHO it would have been better for
first()
to raise an exception when called on an unordered queryset instead of implicitly choosingpk
but in your case I assume you want to eitherorder_by('group')
or'value'
before callingfirst()
.