Opened 4 years ago

Closed 4 years ago

#32044 closed New feature (wontfix)

Add remove_nulls option to Postgres ArrayAgg method

Reported by: Matthieu Rigal Owned by: nobody
Component: contrib.postgres Version: 3.1
Severity: Normal Keywords: postgres, aggregate
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

A common issue when using ArrayAgg is that when the list of values of a related field is empty, it returns [None] instead of []. It is very disturbing the first time one encounters that and led to many stackoverflows questions for example. The issue comes from Postgres itself, however Django could provide an option solve it easily. This is what I want to propose here.

I think we could add a key-word argument, false by default, maybe called remove_nulls, or without_null(s) that would add one of the following:

  1. Auto-filter for null values

As notified in this answer https://stackoverflow.com/a/55107410/1504046 it is possible to filter null values out to prevent the problem. Probably the most efficient solution and I am not aware of downsides to this. Actually, I don't think there is a downside to have it always filtered out (except breaking changes with previous versions)

  1. Use array_remove(, NULL) on the Postgres side

On the Postgres-side, there is a dedicated array_function called array_remove() (existing since 9.3 https://www.postgresql.org/docs/9.3/functions-array.html) which is "less invasive" as it only modifies the result of the output of the select itself, not the query logic behind. It is well described in this answer https://stackoverflow.com/a/33145722/1504046

Cheers,
Matthieu

Change History (1)

comment:1 by Mariusz Felisiak, 4 years ago

Component: Uncategorizedcontrib.postgres
Resolution: wontfix
Status: newclosed

Thanks for this ticket, however ArrayAgg() already supports the filter parameter, so you can use:

ArrayAgg('nullable_field', filter=Q(nullable_field__isnull=False))

I don't see a reason for adding a separate parameter for that specific use.

Note: See TracTickets for help on using tickets.
Back to Top