I have a model called "Employment" in my app, which references two models called "User" and "Company". In the Employments table in the database, there is a composite index on the two foreign keys preventing the same user from having two employments with the same company. I am trying to represent this composite index in Django using the UniqueConstraint class, but it is throwing an error which I cannot find any documentation for.
This model usually works perfectly fine. However, when I add the UniqueConstraint to the model's indexes, the server throws an error. I've looked at the documentation for UniqueConstraint, as well as the rest of Django's documentation, but could not find any mentions of the error I receive. I've also tried replacing 'User_ID' and 'Company_ID' with 'user' and 'company' in the fields argument for UniqueConstraint, but I obtained the exact same error.
Not sure if this is relevant to the issue, but I'm running the Django server with Docker in a python:3.6 container with Django version 2.2.
Here is the Employment model:
from django.db import models
from app.models import User, Company
class Employment(models.Model):
Employment_ID = models.AutoField(primary_key=True)
user = models.ForeignKey(User, db_column='User_ID', on_delete=models.CASCADE)
company = models.ForeignKey(Company, db_column='Company_ID', on_delete=models.CASCADE)
class Meta:
db_table = "Employments"
indexes = [
models.UniqueConstraint(fields=['User_ID', 'Company_ID'],
name='Employment_User_Company_UNIQUE') # server works fine without this
]
When I start my Django server, I get the following output:
Watching for file changes with StatReloader
Performing system checks...
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.6/site-packages/django/utils/autoreload.py", line 54, in wrapper
fn(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 117, in inner_run
self.check(display_num_errors=True)
File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 390, in check
include_deployment_checks=include_deployment_checks,
File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 377, in _run_checks
return checks.run_checks(**kwargs)
File "/usr/local/lib/python3.6/site-packages/django/core/checks/registry.py", line 72, in run_checks
new_errors = check(app_configs=app_configs)
File "/usr/local/lib/python3.6/site-packages/django/core/checks/model_checks.py", line 31, in check_all_models
errors.extend(model.check(**kwargs))
File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 1254, in check
*cls._check_indexes(),
File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 1565, in _check_indexes
fields = [field for index in cls._meta.indexes for field, _ in index.fields_orders]
File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 1565, in <listcomp>
fields = [field for index in cls._meta.indexes for field, _ in index.fields_orders]
AttributeError: 'UniqueConstraint' object has no attribute 'fields_orders'
If anyone has experienced this error or knows of a workaround, I would be very grateful for your insight.
You defined this in the parameter, but this should be in the indexes
constraints
[Django-doc] attribute. indexes
contains, as the name suggests, the list of indexes defined on the table. constraints
on the other hand contains the constraints that should be enforced.
class Employment(models.Model):
Employment_ID = models.AutoField(primary_key=True)
user = models.ForeignKey(User, db_column='User_ID', on_delete=models.CASCADE)
company = models.ForeignKey(Company, db_column='Company_ID', on_delete=models.CASCADE)
class Meta:
db_table = "Employments"
constraints = [
models.UniqueConstraint(
fields=['User_ID', 'Company_ID'],
name='Employment_User_Company_UNIQUE'
)
]