Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.8 'default' option only executes external function once

Tags:

python

django

I am trying to add a UUID field to an existing table. I specified that default = uuid.uuid4 however, it Django doesn't seem to call uuid.uuid4 function for every row. So when I migrate I keep getting duplicated uuid error.

My Django version is 1.8.2.

from django.db import models, migrations
import uuid


class Migration(migrations.Migration):

    dependencies = [
        ('conv', '0008_video_video_uri'),
    ]

    operations = [
        migrations.AddField(
            model_name='conversation',
            name='channel_id',
            field=models.UUIDField(unique=True, default=uuid.uuid4, editable=False),
        ),
    ]

Below the error:

> >  File "/home/yonk/projects/trailerapp/venv/local/lib/python2.7/site-packages/django/db/backends/utils.py",
> line 64, in execute
>     return self.cursor.execute(sql, params) django.db.utils.IntegrityError: could not create unique index
> "conv_conversation_channel_id_68f7d58df7c78d61_uniq" DETAIL:  Key
> (channel_id)=(5f512cbe-e514-4bf5-bf5a-3efd1a94e401) is duplicated.
like image 696
Bonk Avatar asked May 05 '26 05:05

Bonk


1 Answers

Here you have django docs describing exactly what you want: https://docs.djangoproject.com/en/1.8/howto/writing-migrations/#migrations-that-add-unique-fields

You will need two migration files.

  1. First one Adds fields, also change unique=True to null=True so django won't try to use default value...
  2. Second migration populates the field.

So second migration should look like this:

def gen_uuid(apps, schema_editor):
    MyModel = apps.get_model('myapp', 'MyModel')
    for row in MyModel.objects.all():
        row.uuid = uuid.uuid4()
        row.save()


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0004_add_uuid_field'),
    ]

    operations = [
        # omit reverse_code=... if you don't want the migration to be reversible.
        migrations.RunPython(gen_uuid, reverse_code=migrations.RunPython.noop),
    ]
like image 78
Visgean Skeloru Avatar answered May 07 '26 23:05

Visgean Skeloru



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!