Changing the primary key of a model in Django

I had to change the primary key of a django model, and I wanted to create a migration for this.

The previous model was using django automatic primary key fields

I firstly changed the model to include the new uuid field, and added the id field (the old primary key), like this:

    uuid = models.UUIDField(
        unique=True, primary_key=True, default=uuid.uuid4, editable=False
    )
    id = models.IntegerField(null=True, blank=True)

Then I create the migration, they:

To generate the migrations I did django-admin makemigrations, and iterated on it. Here is the migration I ended up with:

import uuid

from django.db import migrations, models

# This is done in pure python, but can probably be faster with SQL queries directly
# for a large database.
def gen_uuid(apps, schema_editor):
    DataLayer = apps.get_model("umap", "DataLayer")
    for row in DataLayer.objects.all():
        row.uuid = uuid.uuid4()
        row.save(update_fields=["uuid"])


class Migration(migrations.Migration):
    dependencies = [
        ("umap", "0017_migrate_to_openstreetmap_oauth2"),
    ]

    operations = [
        migrations.AddField(
            model_name="datalayer",
            name="uuid",
            field=models.UUIDField(default=uuid.uuid4, editable=False, null=True),
        ),
        migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
        migrations.RunSQL(
            "ALTER TABLE umap_datalayer DROP CONSTRAINT umap_datalayer_pkey"
        ),
        migrations.AlterField(
            "datalayer", name="id", field=models.IntegerField(null=True, blank=True)
        ),
        migrations.AlterField(
            model_name="datalayer",
            name="uuid",
            field=models.UUIDField(
                default=uuid.uuid4, editable=False, unique=True, primary_key=True
            ),
        ),
    ]

#django , #orm , #migrations - Posté dans la catégorie code