Django migration with uuid field generates duplicated values

家住魔仙堡 提交于 2019-11-28 22:29:41

Here is an example doing everything in one single migration thanks to a RunPython call.

# -*- coding: utf-8 -*
from __future__ import unicode_literals

from django.db import migrations, models
import uuid


def create_uuid(apps, schema_editor):
    Device = apps.get_model('device_app', 'Device')
    for device in Device.objects.all():
        device.uuid = uuid.uuid4()
        device.save()


class Migration(migrations.Migration):

    dependencies = [
        ('device_app', 'XXXX'),
    ]

    operations = [
        migrations.AddField(
            model_name='device',
            name='uuid',
            field=models.UUIDField(blank=True, null=True),
        ),
        migrations.RunPython(create_uuid),
        migrations.AlterField(
            model_name='device',
            name='uuid',
            field=models.UUIDField(unique=True)
        )
    ]

(Answer taken from the first comment)

See the django docs - Migrations that add unique fields

They recommend changing your single migration into three separate migrations:

  1. Create field, set to null but not unique
  2. Generate unique UUIDs
  3. Alter the field to be unique

In the mode, you have configured, that you want unique values for the uuid fields, but with default values(the same for all). So if you have two 'device' objects in the database, the migrations add 'uuid' field to them with the default 'uuid.uuid4' value and when it tries to set it to the second one, it crashes because of the unique constrains.

If you drop your db and create new objects probably there will be not problems but thats not a solution for production db obviously :D.

A better solution is to create a data migration which sets different uuid value (generated by the default 'uuid' library) to every existing object in the database. You can read more about data migrations here: https://docs.djangoproject.com/en/1.10/topics/migrations/#data-migrations

Then, when you create new objects, django will generate different uuid automatically. ;)

For the primary keys: Django adds it to the model by default.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!