4

The "default" option Django 1.8 only executes the external function on...

 3 years ago
source link: https://www.codesd.com/item/the-default-option-django-1-8-only-executes-the-external-function-once.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

The "default" option Django 1.8 only executes the external function once

advertisements

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.


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),
    ]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK