[Django] #27378: makemigration unable to serialize UUID when UUIDField have choices set

38 views
Skip to first unread message

Django

unread,
Oct 24, 2016, 9:44:16 AM10/24/16
to django-...@googlegroups.com
#27378: makemigration unable to serialize UUID when UUIDField have choices set
-----------------------------+------------------------------------
Reporter: make.kernel | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Keywords: uuid choices migration
Triage Stage: Unreviewed | Has patch: 1
Easy pickings: 0 | UI/UX: 0
-----------------------------+------------------------------------
Using following model

{{{
import uuid
from django.db import models

# Create your models here.

class Student(models.Model):
FRESHMAN = uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8')
SOPHOMORE = uuid.UUID('c7853ec1-2ea3-4359-b02d-b54e8f1bcee2')
JUNIOR = uuid.UUID('94a43637-6dfc-4209-852a-bd9bd8c0101f')
SENIOR = uuid.UUID('dfb9cc50-c332-4809-9b4c-69c81a7489d0')
MENTOR = uuid.UUID('b8f3897a-0a0a-4630-8f1b-1ca4b0ee37ca')
YEAR_IN_SCHOOL_CHOICES = (
(FRESHMAN, 'Freshman'),
(SOPHOMORE, 'Sophomore'),
(JUNIOR, 'Junior'),
(SENIOR, 'Senior'),
(MENTOR, 'Mentor'),
)
year_in_school = models.UUIDField(choices=YEAR_IN_SCHOOL_CHOICES,
default=FRESHMAN)
}}}

According to documentation it should work, and it works until you try to
make migrations for this model, it fails with exception

{{{
Migrations for 'testapp':
testapp/migrations/0001_initial.py:
- Create model Student
Traceback (most recent call last):
File "./manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/core/management/__init__.py", line 367, in
execute_from_command_line
utility.execute()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/core/management/commands/makemigrations.py", line 189, in
handle
self.write_migration_files(changes)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/core/management/commands/makemigrations.py", line 224, in
write_migration_files
migration_string = writer.as_string()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/writer.py", line 163, in as_string
operation_string, operation_imports =
OperationWriter(operation).serialize()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/writer.py", line 120, in serialize
_write(arg_name, arg_value)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/writer.py", line 84, in _write
arg_string, arg_imports = MigrationWriter.serialize(_arg_value)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/writer.py", line 293, in serialize
return serializer_factory(value).serialize()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/serializer.py", line 228, in serialize
return self.serialize_deconstructed(path, args, kwargs)
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/serializer.py", line 100, in
serialize_deconstructed
arg_string, arg_imports = serializer_factory(arg).serialize()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/serializer.py", line 43, in serialize
item_string, item_imports = serializer_factory(item).serialize()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/serializer.py", line 43, in serialize
item_string, item_imports = serializer_factory(item).serialize()
File "/home/yuriy/dev/uuidtest/env/lib/python3.5/site-
packages/django/db/migrations/serializer.py", line 388, in
serializer_factory
"topics/migrations/#migration-serializing" % (value,
get_docs_version())
ValueError: Cannot serialize: UUID('5c859437-d061-4847-b3f7-e6b78852f8c8')
There are some values Django cannot serialize into migration files.
For more, see https://docs.djangoproject.com/en/1.10/topics/migrations
/#migration-serializing
}}}

Here is a small patch that add UUIDSerializer to migration serializers and
tells serializer_factory to use it in case of UUID value

{{{
--- django/db/migrations/serializer.py.orig 2016-10-24
12:16:21.000000000 +0300
+++ django/db/migrations/serializer.py 2016-10-24 15:32:33.908818046
+0300
@@ -6,6 +6,7 @@
import functools
import math
import types
+import uuid
from importlib import import_module

from django.db import models
@@ -319,6 +320,10 @@
else:
return "%s.%s" % (module, self.value.__name__), {"import
%s" % module}

+class UUIDSerializer(BaseSerializer):
+ def serialize(self):
+ return "uuid.UUID('%s')" % self.value, {"import uuid"}
+

def serializer_factory(value):
from django.db.migrations.writer import SettingsReference
@@ -382,6 +387,8 @@
return IterableSerializer(value)
if isinstance(value, (COMPILED_REGEX_TYPE, RegexObject)):
return RegexSerializer(value)
+ if isinstance(value, uuid.UUID):
+ return UUIDSerializer(value)
raise ValueError(
"Cannot serialize: %r\nThere are some values Django cannot
serialize into "
"migration files.\nFor more, see
https://docs.djangoproject.com/en/%s/"
}}}


After applying this change everything works as expected


{{{
(env) yuriy@yuriy-desktop:~/dev/uuidtest/src/uuidtest$ ./manage.py
makemigrations
Migrations for 'testapp':
testapp/migrations/0001_initial.py:
- Create model Student
(env) yuriy@yuriy-desktop:~/dev/uuidtest/src/uuidtest$ ./manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, testapp
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying sessions.0001_initial... OK
Applying testapp.0001_initial... OK
(env) yuriy@yuriy-desktop:~/dev/uuidtest/src/uuidtest$
}}}


migratin produced is


{{{
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-10-24 13:30
from __future__ import unicode_literals

from django.db import migrations, models
import uuid


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Student',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False, verbose_name='ID')),
('year_in_school',
models.UUIDField(choices=[(uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8'),
'Freshman'), (uuid.UUID('c7853ec1-2ea3-4359-b02d-b54e8f1bcee2'),
'Sophomore'), (uuid.UUID('94a43637-6dfc-4209-852a-bd9bd8c0101f'),
'Junior'), (uuid.UUID('dfb9cc50-c332-4809-9b4c-69c81a7489d0'), 'Senior'),
(uuid.UUID('b8f3897a-0a0a-4630-8f1b-1ca4b0ee37ca'), 'Mentor')],
default=uuid.UUID('5c859437-d061-4847-b3f7-e6b78852f8c8'))),
],
),
]
}}}

I have no idea if it is correct, but works for me, if it should be fixed
in other place could you point me where to look?

Thanks

--
Ticket URL: <https://code.djangoproject.com/ticket/27378>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 24, 2016, 10:19:09 AM10/24/16
to django-...@googlegroups.com
#27378: makemigration unable to serialize UUID when UUIDField have choices set
-------------------------------------+-------------------------------------

Reporter: make.kernel | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* needs_better_patch: => 0
* needs_tests: => 0
* version: 1.10 => master
* easy: 0 => 1
* needs_docs: => 0
* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:1>

Django

unread,
Oct 24, 2016, 11:18:39 AM10/24/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: nobody
Type: New feature | Status: new

Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0

Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):

* needs_docs: 0 => 1
* type: Bug => New feature
* needs_tests: 0 => 1


Comment:

Tests and documentation are needed for a complete patch. See
998894e1b9f5a8715f4cac5f6201b5e9ac80510c for a similar commit.

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:2>

Django

unread,
Oct 25, 2016, 3:36:38 AM10/25/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Yuriy Korobko):

* Attachment "uudserializer.patch" added.

Django

unread,
Oct 25, 2016, 3:37:43 AM10/25/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Yuriy Korobko):

Replying to [comment:2 Tim Graham]:


> Tests and documentation are needed for a complete patch. See
998894e1b9f5a8715f4cac5f6201b5e9ac80510c for a similar commit.

Can you please take look into attached patch?

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:3>

Django

unread,
Oct 25, 2016, 8:16:13 AM10/25/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: nobody
Type: New feature | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

Please create a pull request if possible and uncheck "Needs documentation"
and "Needs tests" on the ticket so that it appears in the review queue.

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:4>

Django

unread,
Oct 31, 2016, 4:23:14 PM10/31/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: Maxime
| Lorant
Type: New feature | Status: assigned

Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Maxime Lorant):

* owner: nobody => Maxime Lorant
* needs_docs: 1 => 0
* status: new => assigned
* needs_tests: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:5>

Django

unread,
Oct 31, 2016, 8:52:53 PM10/31/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: Maxime
| Lorant
Type: New feature | Status: assigned
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

[https://github.com/django/django/pull/7458 PR]

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:6>

Django

unread,
Nov 5, 2016, 7:17:18 AM11/5/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: Tobias
| McNulty

Type: New feature | Status: assigned
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tobias McNulty):

* owner: Maxime Lorant => Tobias McNulty


Comment:

Reviewing this now (at the DUTH sprint).

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:7>

Django

unread,
Nov 5, 2016, 8:02:05 AM11/5/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: (none)
Type: New feature | Status: new

Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Accepted
migration |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tobias McNulty):

* status: assigned => new
* needs_better_patch: 0 => 1
* owner: Tobias McNulty => (none)


--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:8>

Django

unread,
Nov 5, 2016, 5:15:53 PM11/5/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: (none)
Type: New feature | Status: new
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: uuid choices | Triage Stage: Ready for
migration | checkin

Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin


Comment:

Patch does LGTM.

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:9>

Django

unread,
Nov 6, 2016, 7:53:08 AM11/6/16
to django-...@googlegroups.com
#27378: Add UUID serialization support to migration writer
-------------------------------------+-------------------------------------
Reporter: Yuriy Korobko | Owner: Tim
| Graham <timograham@…>
Type: New feature | Status: closed
Component: Migrations | Version: master
Severity: Normal | Resolution: fixed

Keywords: uuid choices | Triage Stage: Ready for
migration | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: new => closed
* owner: (none) => Tim Graham <timograham@…>
* resolution: => fixed


Comment:

In [changeset:"cb3fb34b86b17349ec428e789585d0da9604804a" cb3fb34b]:
{{{
#!CommitTicketReference repository=""
revision="cb3fb34b86b17349ec428e789585d0da9604804a"
Fixed #27378 -- Added support for serialization of uuid.UUID in
migrations.

Thanks Yuriy Korobko for the initial patch and Tobias McNulty for review.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/27378#comment:10>

Reply all
Reply to author
Forward
0 new messages