Django migration- How to fix uniqueness=True on migration (backwards)?
A field in my model used to have no constraints.
But in order to avoid problems in the future i need to make the field unique=True
.
This will obviously raise a Key (field)=(foo) is duplicated
What is the best practice to fix that migration backwards in order to not raise an error?
The constraint is applied at the database level, so if you have existing data in your table that does not satisfy the constraint you cannot avoid the error. Before setting unique=True
you must remove duplicate values or change them. Otherwise you could validate the uniqueness in the model save
method or in a form/serializer validation instead of using a db constraint.
This depends on how you are migrating things.
If you can take down the database while you migrate, then it's much simpler.
- Remove all duplicates.
- Add the unique flag.
Do both these things as part of the migration.
If, on the other hand, you need to keep things up and running, then it's a 3 step process:
Add validation to any code that creates a record in this table (mostly
save
methods in all likelihood, but watch out for other stuff), so that adding more duplicate values is not possible. (It may help to add an index to the table on the unique field for this, but may not be necessary depending on the size of the data, performance requirements etc.)Once this is in place and you know you only have old duplicates in the DB, and no more can be added, delete those duplicates according to whatever rules you use to determine which records to remove.
Finally, run a migration to add the
unique
flag to the field.
2 & 3 could both be done from the migration script, but it's important step 1 is complete first so you don't get new dups added while or after you're cleaning things up.