python django uuid django-migrations

python - La migración de Django con el campo uuid genera valores duplicados.



django y python (3)

Tengo un campo uuid (no una clave principal). La migración generada es:

from __future__ import unicode_literals from django.db import migrations, models import uuid class Migration(migrations.Migration): dependencies = [ .... ] operations = [ ... migrations.AddField( model_name=''device'', name=''uuid'', field=models.UUIDField(default=uuid.uuid4, unique=True), ), ... ]

Pero al hacer python manage.py migrate se bloquea con:

django.db.utils.IntegrityError: no se pudo crear el índice único "restaurants_device_uuid_key" DETALLE: La clave (uuid) = (f3858ded-b8e0-4ac0-8436-8a61b10efc73) está duplicada.

Por extraño que parezca, el problema no parece ocurrir con las claves primarias (que tal vez son creadas por la base de datos y no internamente por django)

¿Cómo puedo agregar un campo uuid y asegurarme de que las migraciones funcionen?


(Respuesta tomada del primer comentario)

Ver los documentos de django - Migraciones que agregan campos únicos

Recomiendan cambiar su migración individual a tres migraciones separadas:

  1. Crear campo, establecer en nulo pero no único
  2. Generar UUIDs únicos
  3. Altera el campo para que sea único.

Aquí hay un ejemplo que hace todo en una sola migración gracias a una llamada RunPython.

# -*- 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) ) ]


En el modo, ha configurado que desea valores únicos para los campos de uuid, pero con valores predeterminados (los mismos para todos). Entonces, si tiene dos objetos ''dispositivo'' en la base de datos, las migraciones les agregan el campo ''uuid'' con el valor predeterminado ''uuid.uuid4'' y cuando intenta establecerlo en el segundo, se bloquea debido a las restricciones únicas. .

Si suelta su base de datos y crea nuevos objetos, probablemente no habrá problemas, pero eso no es una solución para la producción de bases de datos, obviamente: D.

Una mejor solución es crear una migración de datos que establezca un valor uuid diferente (generado por la biblioteca ''uuid'' predeterminada) para cada objeto existente en la base de datos. Puede leer más sobre las migraciones de datos aquí: https://docs.djangoproject.com/en/1.10/topics/migrations/#data-migrations

Luego, cuando crees nuevos objetos, django generará uuid diferente automáticamente. ;)

Para las claves principales: Django lo agrega al modelo por defecto.