15đź‘Ť
Actually, the source or your issue is not the unique constraint by itself but the fact that your field doesn’t allow nulls and has no default value – you’d have the very same error with a non-unique field.
The proper solution here is to allow the field to be null (null=True
) and default it to None
(which will translate to sql “null”). Since null
values are excluded from unique constraints (at least if your db vendor respects SQL standard), this allow you to apply the schema change while still making sure you cannot have a duplicate for non-null values.
Then you may want a data migration to load the known “other_id” values, and eventually a third schema migration to disallow null values for this field – if and only if you know you have filled this field for all records.
11đź‘Ť
Django has something called Data Migrations where you create a migration file that modifies/remove/add data to your database as you apply your migrations.
In this case you would create 3 different migrations:
- Create a migration that allow null values with
null=True
. - Create a data migration that populate the data.
- Create a migration that disallow null values by removing the
null=True
added in step 1.
As you then run python manage.py migrate
it would apply all of the migrations in step 1-3 in the correct order.
Your data migration would look something like this:
from django.db import migrations
def populate_reference(apps, schema_editor):
MyModel = apps.get_model('yourappname', 'MyModel')
for obj in MyModel.objects.all():
obj.other_id = random_id_generator()
obj.save()
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(populate_reference),
]
You can create an empty migration file using the ./manage.py makemigrations --empty yourappname
command.
- Heroku Django DEBUG Setting not applied
- How to retrieve all permissions of a specific model in django?
- How to represent month as field on django model