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.13.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_check_constraint-1.0.13-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django-check-constraint-1.0.13.tar.gz
  • Upload date:
  • Size: 9.1 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.13.tar.gz
Algorithm Hash digest
SHA256 8dde7e6b06b5a7f98c2cbc2d4854e7e8e81c2b08d25dc35d622a5865a0b74c92
MD5 550d4bb7ac537e633494bf9b1475fbf8
BLAKE2b-256 25b763e8028014183d219df214ba8d06bd3944ccc3926357fc680d99ab33b1d0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: django_check_constraint-1.0.13-py3-none-any.whl
  • Upload date:
  • Size: 13.9 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.13-py3-none-any.whl
Algorithm Hash digest
SHA256 008353fc2b7bfa56c7795306d9aa64c567acaf378e7f2b808396c915d93e9f5c
MD5 0cea101206f6e253cd45c3b22ef8f9a4
BLAKE2b-256 60c5b1cbd92926e4702e7092fef53dfbd855cc7116af294f26bbbb060f83fc85

See more details on using hashes here.

Supported by

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