Skip to main content

Extends django check constraint to support annotations.

Project description

django-check-constraint

django check constraint test. PyPI version PyPI - License PyPI - Python Version PyPI - Django Version Upload Python Package Create New Release

Extends Django's Check constraint with support for UDF(User defined functions/db functions) and annotations.

Installation

$ pip install django-check-constraint

ADD check_constraint to list of INSTALLED APPS.

INSTALLED_APPS = [
  ...
  "check_constraint",
  ...
]

Scenario:

Suppose you have a database function that returns the counts of null values in [i, ...n].

CREATE OR REPLACE FUNCTION public.non_null_count(VARIADIC arg_array ANYARRAY)
  RETURNS BIGINT AS
  $$
    SELECT COUNT(x) FROM UNNEST($1) AS x
  $$ LANGUAGE SQL IMMUTABLE;

Example:

SELECT public.non_null_count(1, null, null);

Outputs:

non_null_count
----------------
              1
(1 row)

Defining a check constraint with this function

The equivalent of (PostgresSQL)

ALTER TABLE app_name_test_modoel ADD CONSTRAINT app_name_test_model_optional_field_provided
    CHECK(non_null_count(amount::integer , amount_off::integer, percentage::integer) = 1);

Usage

Converting this to django functions and annotated check contraints can be done using:

function.py

from django.db.models import Func, SmallIntegerField, TextField
from django.db.models.functions import Cast


class NotNullCount(Func):
    function = 'non_null_count'

    def __init__(self, *expressions, **extra):
        filter_exp = [
            Cast(exp, TextField()) for exp in expressions if isinstance(exp, str)
        ]
        if 'output_field' not in extra:
            extra['output_field'] = SmallIntegerField()

        if len(expressions) < 2:
            raise ValueError('NotNullCount must take at least two expressions')

        super().__init__(*filter_exp, **extra)

Creating annotated check constraints

from django.db import models
from django.db.models import Q
from check_constraint.models import AnnotatedCheckConstraint

class TestModel(models.Model):
    amount = models.DecimalField(max_digits=9, decimal_places=2, null=True, blank=True)
    amount_off = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
    percentage = models.DecimalField(max_digits=3, decimal_places=0, null=True, blank=True)


    class Meta:
        constraints = [
            AnnotatedCheckConstraint(
                check=Q(not_null_count=1),
                annotations={
                    'not_null_count': (
                        NotNullCount(
                            'amount',
                            'amount_off',
                            'percentage',
                        )
                    ),
                },
                name='%(app_label)s_%(class)s_optional_field_provided',
            ),
        ]

TODO's

  • Add support for schema based functions.
  • Add warning about mysql lack of user defined check constraint support.
  • Remove skipped sqlite3 test.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-check-constraint-1.0.18.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

django_check_constraint-1.0.18-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file django-check-constraint-1.0.18.tar.gz.

File metadata

  • Download URL: django-check-constraint-1.0.18.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.6.10

File hashes

Hashes for django-check-constraint-1.0.18.tar.gz
Algorithm Hash digest
SHA256 e1fc7074def6a21576a3170f59e0c656163f81c0fb2962723980016877e35f07
MD5 466c000560b90ffeb52b508f1ace4e79
BLAKE2b-256 d330d113b6f1a2f0a0422f5853ec49885bdd1bd59a9634b751d834a505609cf5

See more details on using hashes here.

File details

Details for the file django_check_constraint-1.0.18-py3-none-any.whl.

File metadata

  • Download URL: django_check_constraint-1.0.18-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/45.2.0 requests-toolbelt/0.9.1 tqdm/4.43.0 CPython/3.6.10

File hashes

Hashes for django_check_constraint-1.0.18-py3-none-any.whl
Algorithm Hash digest
SHA256 2dd1942d1314415ab93b7a2242a34139b576069b58d9aaeb70b810cc13f6578f
MD5 e23b635194d38c0705b25f9d5f0829d6
BLAKE2b-256 1c741d10331fbce9104a9d669c816a304863e3cc114a4d3824279a712459a61d

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page