|
#Design decisions on aggregate/annotate behaviour IntroductionHere is a list of desing decisions that have been taken on the behaviour of aggregates by the comunity (for big decisions) or by me (for small decisions). If you have any questions/sugestion, please post on django-dev or contact me directly. Design Decisions- Aplying aggregate() after extra() or values() does not do group_by but discard any changes made to the select set by these two modifiers. This is to explicitly mark the difference between annotate and aggregate. For grouping use annotate.
- When doing aggregate/annotate on related fields the default behaviour is to join using INNER JOIN. This implies that the objects for which the aggregated value is null wont appear in the result. To include all the objects in the result a new parameter allow_nulls is introduced. This parameter promotes the joins to always use LEFT OUTER JOIN getting all the objects that matched the query to appear in the result. Those objects that had a null aggregated value will have None when queried for the aggregated alias.
In words everybody understands:
#In the following example the author who has no friends, Brad Dayley (My apologies to Brad Dayley, the choice of friends was completly random), will not appear in the results.
>>> authors = Author.objects.all().annotate(Avg('friends__age')).order_by('id')
>>> len(authors)
8
>>> for i in authors:
... print i.name, i.friends__age__avg
...
Adrian Holovaty 32.0
Jacob Kaplan-Moss 29.5
James Bennett 34.0
Jeffrey Forcier 27.0
Paul Bissex 31.0
Wesley J. Chun 33.6666666667
Peter Norvig 46.0
Stuart Russell 57.0
#To include every object retrieved by the previous query, Author.objects.all(), whether they have a m2m relationship or not we use the allow_nulls parameter.
#Notice that this affects the performance at the database level so try to avoid it if possible
>>> authors = Author.objects.all().annotate(Avg('friends__age'), allow_nulls=True).order_by('id')
>>> len(authors)
9
>>> for i in authors:
... print i.name, i.friends__age__avg
...
Adrian Holovaty 32.0
Jacob Kaplan-Moss 29.5
Brad Dayley None
James Bennett 34.0
Jeffrey Forcier 27.0
Paul Bissex 31.0
Wesley J. Chun 33.6666666667
Peter Norvig 46.0
Stuart Russell 57.0
This decision has changed. Now Joins are always promoted. In the future a better analysis should be made to decide which joins to promote if possible.
|