跳转到主要内容

扩展django check constraint以支持注解。

项目描述

django-check-constraint

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

扩展 Django的Check 约束,支持UDF(用户定义函数/数据库函数)和注解。

安装

$ pip install django-check-constraint

check_constraint 添加到 INSTALLED APPS 列表中。

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

场景

假设你有一个数据库函数,该函数返回 [i, ...n] 中null值的计数。

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;

示例

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

输出

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

使用此函数定义检查约束

(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);

用法

可以使用以下方式将此转换为django函数和注解检查约束:

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)

创建注解检查约束

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',
            ),
        ]

待办事项

  • 添加对基于模式的函数的支持。
  • 添加关于MySQL缺少用户定义检查约束支持的警告。
  • 删除跳过的sqlite3测试。

项目详情


下载文件

下载您平台对应的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

django-check-constraint-1.0.18.tar.gz (13.6 kB 查看散列值)

上传时间 源代码

构建分布

django_check_constraint-1.0.18-py3-none-any.whl (14.5 kB 查看散列值)

上传时间 Python 3

AWSAWS 云计算和安全赞助商 DatadogDatadog 监控 FastlyFastly CDN GoogleGoogle 下载分析 MicrosoftMicrosoft PSF赞助商 PingdomPingdom 监控 SentrySentry 错误日志 StatusPageStatusPage 状态页面