Opened 3 hours ago
#36981 new New feature
Add PostgreSQL num_nonnulls (code provided)
| Reported by: | Robin Christ | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.0 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description
I recently implemented "anyOf" / "tagged union" fields. I added specialized CheckConstraints using num_nonnulls
The code looks like this:
class NumNonNulls(Func):
"""
Wraps PostgreSQL `num_nonnulls`.
Returns the number of non-null arguments as an integer. Can be used with
`F()` references to model fields (including e.g. OneToOne) relationships.
Example::
NumNonNulls(F("one_to_one_rel_1"), F("one_to_one_rel_1"))
-> SQL: num_nonnulls("one_to_one_rel_1_id", "one_to_one_rel_2_id")
"""
function = "num_nonnulls"
def __init__(self, *expressions: object, **extra) -> None:
super().__init__(*expressions, output_field=IntegerField(), **extra)
class NumNonNullsEq(Func):
"""
Renders ``num_nonnulls(<args>) = <n>`` as a boolean expression.
Suitable for use as the `condition` of a `CheckConstraint`.
Parameters
----------
*expressions:
The expressions (e.g. `F()` expressions) to pass to `num_nonnulls`.
count:
The value or expression the result must equal.
Example::
NumNonNullsEq(F("one_to_one_rel_1"), F("one_to_one_rel_2"), count=1)
-> SQL: num_nonnulls("one_to_one_rel_1_id", "one_to_one_rel_2_id") = 1
"""
arg_joiner = " = "
template = "%(expressions)s"
def __init__(self, *expressions: object, count: object, **extra) -> None:
if not expressions:
raise ValueError("NumNonNullsEq() requires at least one expression.")
super().__init__(
NumNonNulls(*expressions),
count,
output_field=BooleanField(),
)
Is there any interest from Django's side in this?
Note:
See TracTickets
for help on using tickets.