Why does Django with sqlite not insert unique constraint into the database schema?

Viewed 377

I am starting to use Django with sqlite and I want to impose a simple unique constraint on the combination of two fields in a table. To this end, I use Django's UniqueConstraint class. However, to my surprise, the constraint is not inserted in to the tables schema in the database. My Django model looks like follows:

from django.db import models

class Fruit(models.Model):
    fruit_id = models.IntegerField(primary_key=True)
    fruit_type = models.CharField(max_length=64, default='', blank=True, null=False)
    fruit_name = models.CharField(max_length=128, default='', blank=True, null=False)
    class Meta:
        models.UniqueConstraint(fields=['fruit_type', 'fruit_name'], name='unique_fruit_type_name')
        db_table = 'fruit'

After migration, I check the schema in the database by executing:

select sql from sqlite_master where type='table';

The result, for the table in question, reads:

CREATE TABLE "fruit" ("fruit_id" integer NOT NULL PRIMARY KEY"fruit_type" varchar(64) NOT NULL), "fruit_name" varchar(128) NOT NULL

I was expecting to get:

CREATE TABLE "fruit" ("fruit_id" integer NOT NULL PRIMARY KEY"fruit_type" varchar(64) NOT NULL), "fruit_name" varchar(128) NOT NULL, UNIQUE (fruit_type, fruit_name)

Where did the UNIQUE-clause go? Is it not supposed to be in the schema?

1 Answers

You write the constraint directly in the Meta class which has no effect. You instead need to write it in a list on the attribute constraints [Django docs] in the Meta class:

from django.db import models

class Fruit(models.Model):
    fruit_id = models.IntegerField(primary_key=True)
    fruit_type = models.CharField(max_length=64, default='', blank=True, null=False)
    fruit_name = models.CharField(max_length=128, default='', blank=True, null=False)
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['fruit_type', 'fruit_name'], name='unique_fruit_type_name')
        ]
        db_table = 'fruit'

Note: Make sure to run python manage.py makemigrations and python manage.py migrate after making these changes.

Related