#34808: Some aggregation functions may return None; this isn't well documented
------------------------------------------------+------------------------
Reporter: Eric Baumgartner | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Documentation | Version: 4.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
Calls like Book.objects.filter(...).aggregate(Sum("pages")) may return
None if the queryset is empty.
This isn't well documented and I think many of the examples in the
documentation can lead to folks writing unsafe code that works most of the
time, but can fail for empty queries.
For example (using models from
https://docs.djangoproject.com/en/4.2/topics/db/aggregation/):
{{{#!python
obscure_publisher = ...
q =
Book.objects.filter(publisher=obscure_publisher).Aggregate(Sum("pages"))
total_pages = q["pages"] # None if the publisher hasn't published any
books!
# Silly example, but will raise a TypeError
kilopages = total_pages / 1000
}}}
From what I've seen online, I think the safer approach is to use Coalesce.
{{{#!python
obscure_publisher = ...
q =
Book.objects.filter(publisher=obscure_publisher).Aggregate(Coalesce(Sum("pages"),
0)
total_pages = q["pages"] # Safe; using coalesce guarantees an int.
}}}
The only reference I've found to using Coalesce in this way appears to be
a usage example at https://docs.djangoproject.com/en/4.2/ref/models
/database-functions/#coalesce. Coalesce is not mentioned at all on the
main aggregation page.
I think the documentation could be improved in a few ways.
On https://docs.djangoproject.com/en/4.2/topics/db/aggregation/:
- The code examples could consider adding Coalesce, or at least adding a
comment at the top of the cheat sheet section mentioning that the examples
do not include error checking and that using Coalesce is best practice.
For aggregation functions mentioned in
https://docs.djangoproject.com/en/4.2/ref/models/querysets/:
- Add something to the documentation of the return type for functions used
by aggregate() that mentions the empty queryset case if the result type
differs for empty queries.
- For example, Count() safely returns an int even with empty querysets,
but Sum, Avg, Min, and Max do not.
- Might also be worth mentioning that one can use Coalesce to avoid having
to deal with None values.
--
Ticket URL: <https://code.djangoproject.com/ticket/34808>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018a4e32cbcc-acf7f296-2855-4845-a4fb-6b3d952f13ad-000000%40eu-central-1.amazonses.com.