Opened 3 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#36981 closed New feature (needsnewfeatureprocess)

Add PostgreSQL num_nonnulls (code provided)

Reported by: Robin Christ Owned by: Shubh Rai
Component: Database layer (models, ORM) Version: 6.0
Severity: Normal Keywords:
Cc: Shubh Rai Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no 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?

Change History (4)

comment:1 by Shubh Rai, 3 weeks ago

Cc: Shubh Rai added
Owner: set to Shubh Rai
Status: newassigned

comment:2 by Shubh Rai, 3 weeks ago

I have submitted a pr - https://github.com/django/django/pull/20899. I did not add the test file but i tested it on my local, I did not add the test file,as I believe the changes should be as minimal as possible. Please review it and let me know if any changes are required.

comment:3 by Natalia Bidart, 3 weeks ago

Easy pickings: unset
Resolution: needsnewfeatureprocess
Status: assignedclosed

Thank you for your suggestion! When suggesting a new feature for Django, the feature idea should first be proposed and discussed with the community. To do that, please raise this on the new feature tracker.

I'll close the ticket for now, but if the community agrees with the proposal, please return to this ticket and reference the forum discussion so we can re-open it. For more information, please refer to the documented guidelines for requesting features.

Thanks again!

in reply to:  3 comment:4 by Shubh Rai, 3 weeks ago

thank you for the clarification I believe it falls in new feature process.For now I am closing my pr, If in future this ticket gets accepted I will reopen my pr.

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