[Django] #36638: The default for ArrayAgg should be an empty list rather than None

10 views
Skip to first unread message

Django

unread,
Oct 3, 2025, 11:05:55 AM (3 days ago) Oct 3
to django-...@googlegroups.com
#36638: The default for ArrayAgg should be an empty list rather than None
-------------------------------------+-------------------------------------
Reporter: Markus Amalthea | Type:
Magnuson | Uncategorized
Status: new | Component:
| Uncategorized
Version: 5.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
-------------------------------------+-------------------------------------
I would expect (in Python, broadly) a function that returns a list of
values to always return a list. What is the reasoning behind this not
being the case for ArrayAgg? Instead, the default value is `None` when
there are no values, and I'm sure there is a good reason for this.
--
Ticket URL: <https://code.djangoproject.com/ticket/36638>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 3, 2025, 11:34:00 AM (3 days ago) Oct 3
to django-...@googlegroups.com
#36638: The default for ArrayAgg should be an empty list rather than None
-------------------------------------+-------------------------------------
Reporter: Markus Amalthea | Owner: (none)
Magnuson |
Type: Uncategorized | Status: closed
Component: contrib.postgres | Version: 5.2
Severity: Normal | Resolution: invalid
Keywords: ArrayAgg | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* component: Uncategorized => contrib.postgres
* keywords: => ArrayAgg
* resolution: => invalid
* status: new => closed

Comment:

See #10929 and fee87345967b3d917b618533585076cbfa43451b: Django used to do
that, but deprecated it and removed it in 5.0, due to it being
inconsistent with other aggregates. (The inconsistency was a compromise
given the lack of `default` at the time.)

You can use `default=Value([])` if you prefer. See
https://docs.djangoproject.com/en/5.2/releases/4.0/#id2.
--
Ticket URL: <https://code.djangoproject.com/ticket/36638#comment:1>

Django

unread,
Oct 3, 2025, 12:13:01 PM (3 days ago) Oct 3
to django-...@googlegroups.com
#36638: The default for ArrayAgg should be an empty list rather than None
-------------------------------------+-------------------------------------
Reporter: Markus Amalthea | Owner: (none)
Magnuson |
Type: Uncategorized | Status: closed
Component: contrib.postgres | Version: 5.2
Severity: Normal | Resolution: invalid
Keywords: ArrayAgg | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):

> You can use `default=Value([])` if you prefer.

You don't have to do the `Values` wrapping, passing `default=[]` works
just fine.

`Value` wrapping is only necessary when passing a `str` literal as they
default to field references instead of literals like any other Python
literal does (`'field'` is equivalent `F('field')`)
--
Ticket URL: <https://code.djangoproject.com/ticket/36638#comment:2>

Django

unread,
Oct 3, 2025, 12:19:10 PM (3 days ago) Oct 3
to django-...@googlegroups.com
#36638: The default for ArrayAgg should be an empty list rather than None
-------------------------------------+-------------------------------------
Reporter: Markus Amalthea | Owner: (none)
Magnuson |
Type: Uncategorized | Status: closed
Component: contrib.postgres | Version: 5.2
Severity: Normal | Resolution: invalid
Keywords: ArrayAgg | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Markus Amalthea Magnuson):

Why is `[]` safe to use here (rather than `list`)?
--
Ticket URL: <https://code.djangoproject.com/ticket/36638#comment:3>

Django

unread,
Oct 3, 2025, 1:00:06 PM (3 days ago) Oct 3
to django-...@googlegroups.com
#36638: The default for ArrayAgg should be an empty list rather than None
-------------------------------------+-------------------------------------
Reporter: Markus Amalthea | Owner: (none)
Magnuson |
Type: Uncategorized | Status: closed
Component: contrib.postgres | Version: 5.2
Severity: Normal | Resolution: invalid
Keywords: ArrayAgg | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Jacob Walls):

Django never mutates the value; it just sends it to the db adapter to
include in the query.
--
Ticket URL: <https://code.djangoproject.com/ticket/36638#comment:4>

Django

unread,
Oct 3, 2025, 1:41:01 PM (3 days ago) Oct 3
to django-...@googlegroups.com
#36638: The default for ArrayAgg should be an empty list rather than None
-------------------------------------+-------------------------------------
Reporter: Markus Amalthea | Owner: (none)
Magnuson |
Type: Uncategorized | Status: closed
Component: contrib.postgres | Version: 5.2
Severity: Normal | Resolution: invalid
Keywords: ArrayAgg | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):

In other words, the `ARRAY_AGG` Postgres function returns `NULL`
[https://www.postgresql.org/docs/current/functions-aggregate.html on an
empty set].

Passing `default=[]` wraps the `ARRAY_AGG` in `COALESCE` to default to the
provided value

{{{#!sql
SELECT COALESCE(ARRAY_AGG(field), '{}'::text[])
}}}

Per Postgres documentation linked above

> It should be noted that except for `count`, these functions return a
null value when no rows are selected. In particular, `sum` of no rows
returns null, not zero as one might expect, and `array_agg` returns null
rather than an empty array when there are no input rows. The `coalesce`
function can be used to substitute zero or an empty array for null when
necessary.
--
Ticket URL: <https://code.djangoproject.com/ticket/36638#comment:5>
Reply all
Reply to author
Forward
0 new messages