Adding a unique together constraint concurrently

Adrienne Domingus
3 min readJan 1, 2018

Adding a unique_together constraint to a database model in Django is easy. Add it to the Meta class on your model, makemigrations, migrate, and voilà. This works well if you’re creating a new table, or if you have a low traffic application/low-volume table that won’t take long to migrate. However, in order to add a uniqueness constraint, an index must first be created (so that lookups to confirm if a duplicate already exists can be done quickly). This can be problematic. According to the Postgres docs:

…a standard index build locks out writes (but not reads) on the table until it’s done

This means that while your migration is running, no writes can be made to the table on which the constraint is being added, which, depending on the size of the table, can take some time. In order to avoid locking the table to ensure that user actions can continue to take place during the migration, we’ll have to create the index concurrently, which means we’ll have to do it with raw SQL, instead of using Django’s built-in migrations.

I’d still recommend adding the uniqueness constraint to the Meta class on your model and generating the migration file. You can then run the migration file by running python manage.py migrate <app> <migration_file> --fake. This doesn’t actually run the migration, but it does add it to your django_migrations table, which ensures that once you’re finished, your model definition will match what is in the database, and the next time you try to generate or run…

--

--