All Projects → shangxiao → django-db-constraints

shangxiao / django-db-constraints

Licence: MIT license
Add database table-level constraints to your Django model's Meta

Programming Languages

python
139335 projects - #7 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to django-db-constraints

Clpfd
Constraint Logic Programming over Finite Domains
Stars: ✭ 120 (+179.07%)
Mutual labels:  constraints
Composer Patches
Applies a patch from a local or remote file to any package that is part of a given composer project. Patches can be defined both on project and on package level. Optional support for patch versioning, sequencing, custom patch applier configuration and composer command for testing/troubleshooting patches.
Stars: ✭ 196 (+355.81%)
Mutual labels:  constraints
conjure
Conjure: The Automated Constraint Modelling Tool
Stars: ✭ 84 (+95.35%)
Mutual labels:  constraints
Reactive record
Generate ActiveRecord models for a pre-existing Postgres db
Stars: ✭ 132 (+206.98%)
Mutual labels:  constraints
Logician
Logic programming in Swift
Stars: ✭ 182 (+323.26%)
Mutual labels:  constraints
Core Layout
Flexbox & CSS-style Layout in Swift.
Stars: ✭ 215 (+400%)
Mutual labels:  constraints
Snapkitextend
SnapKit的扩展,SnapKit类似于Masonry,但是其没有对Arry的设置和对等间距排列的布局等,此扩展是类似Masonry的写法对SnapKit的补充,同时补充九宫格布局方式
Stars: ✭ 110 (+155.81%)
Mutual labels:  constraints
PyMiniSolvers
A Python API for the MiniSat and MiniCard constraint solvers.
Stars: ✭ 18 (-58.14%)
Mutual labels:  constraints
Optaplanner
AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.
Stars: ✭ 2,454 (+5606.98%)
Mutual labels:  constraints
StoryboardConstraint
A simple way to use programmatically Autolayout Constraint created in Storyboard.
Stars: ✭ 25 (-41.86%)
Mutual labels:  constraints
Easypeasy
Auto Layout made easy
Stars: ✭ 1,877 (+4265.12%)
Mutual labels:  constraints
Joiful
TypeScript Declarative Validation for Joi
Stars: ✭ 177 (+311.63%)
Mutual labels:  constraints
Fluid For Sketch
[Sketch Plugin] Sketch-flavored Auto Layout-like Constraints
Stars: ✭ 2,408 (+5500%)
Mutual labels:  constraints
Elpi
Embeddable Lambda Prolog Interpreter
Stars: ✭ 126 (+193.02%)
Mutual labels:  constraints
ciao
Ciao is a modern Prolog implementation that builds up from a logic-based simple kernel designed to be portable, extensible, and modular.
Stars: ✭ 190 (+341.86%)
Mutual labels:  constraints
React Form With Constraints
Simple form validation for React
Stars: ✭ 117 (+172.09%)
Mutual labels:  constraints
Arranged
Open source replacement of UIStackView for iOS 8 (100% layouts supported)
Stars: ✭ 202 (+369.77%)
Mutual labels:  constraints
Formidable
The PHP pragmatic forms library
Stars: ✭ 116 (+169.77%)
Mutual labels:  constraints
mv-postgresql
Postgresql constraints in migrations similiar to ActiveRecord validations
Stars: ✭ 19 (-55.81%)
Mutual labels:  constraints
pycsp3
A Python Library for modeling combinatorial constrained problems
Stars: ✭ 39 (-9.3%)
Mutual labels:  constraints

django-db-constraints

What is this?

Add database table-level constraints to your Django model's Meta class and have makemigrations add the appropriate migration.

class Foo(models.Model):
    bar = models.IntegerField()
    baz = models.IntegerField()

    class Meta:
        db_constraints = {
            'bar_equal_baz': 'check (bar = baz)',
        }

This should generate a migration like so:

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Foo',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('bar', models.IntegerField()),
                ('baz', models.IntegerField()),
            ],
        ),
        django_db_constraints.operations.AlterConstraints(
            name='Foo',
            db_constraints={'bar_equal_baz': 'check (bar = baz)'},
        ),
    ]

The resulting SQL applied:

CREATE TABLE "sample_foo" ("id" serial NOT NULL PRIMARY KEY, "bar" integer NOT NULL, "baz" integer NOT NULL)
ALTER TABLE "sample_foo" ADD CONSTRAINT "bar_equal_baz" check (bar = baz)

Composite foreign keys

It's possible to support composite foreign keys if you have a unique key on your reference model:

(Why are composite foreign keys useful?)

class Bar(models.Model):
    baz = models.IntegerField()

    class Meta:
        unique_together = ('id', 'baz')


class Foo(models.Model):
    bar = models.ForeignKey(Bar)
    baz = models.IntegerField()

    class Meta:
        db_constraints = {
            'composite_fk': 'foreign key (bar_id, baz) references sample_bar (id, baz)',
        }

Results in:

ALTER TABLE "sample_foo" ADD CONSTRAINT "composite_fk" foreign key (bar_id, baz) references sample_bar (id, baz)

Notes

Migration operation ordering

Given that nothing will depend on a constraint operation, they're simply added to the end of the list of operations for a migration. This includes operations that drop fields used in a constraint as the database drop will any related constraints as well (at least with PostgreSQL).

Caveats

It's possible to end up in a situation where the constraints are declared on the Meta class but do not exist in the database due to a database dropping a constraint implicitly when a field in the constraint is dropped.

Please test your constraints!

I encourage folks to write tests for their constraints to ensure they write are actually applied in the database.

Acknowledgements

Thanks to @schinckel and @MarkusH for their advice and ideas.

Installation

pip install django-db-constraints

in your settings.py:

INSTALLED_APPS = [
    'django_db_constraints',
    …
]
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].