Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/shangxiao/django-db-constraints
Add database table-level constraints to your Django model's Meta
https://github.com/shangxiao/django-db-constraints
constraints database django
Last synced: 12 days ago
JSON representation
Add database table-level constraints to your Django model's Meta
- Host: GitHub
- URL: https://github.com/shangxiao/django-db-constraints
- Owner: shangxiao
- License: mit
- Created: 2017-08-02T19:31:45.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2020-04-01T18:01:26.000Z (over 4 years ago)
- Last Synced: 2024-10-06T15:11:04.224Z (about 1 month ago)
- Topics: constraints, database, django
- Language: Python
- Homepage:
- Size: 9.77 KB
- Stars: 44
- Watchers: 4
- Forks: 4
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 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.
```python
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:
```python
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:
```sql
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?](https://github.com/rapilabs/blog/blob/master/articles/same-parent-db-pattern.md))
```python
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:
```sql
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:
```python
INSTALLED_APPS = [
'django_db_constraints',
…
]
```