#23226: Migrations generated by python2 break when using python3 to migrate ---------------------------------+---------------------------------------- Reporter: morshed.nader@… | Owner: andrewgodwin Type: Bug | Status: assigned Component: Migrations | Version: 1.7-rc-2 Severity: Release blocker | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 ---------------------------------+----------------------------------------
Comment (by charettes): Replying to [comment:6 andrewgodwin]: > I'm in two minds as to whether we should just force-convert everything to Unicode in migration files (which obviously is technically changing data, and might break with strings intended for humans to read), or document that you should be using unicode for your models files. > > There's a potential third outcome here where we fix the state stuff to convert all model names/field names to unicode, which would solve most immediate problems. I'll investigate. The thing is that it's hard to which part needs fixing to solve the immediate problem. Take `order_with_respect_to` for example: {{{#!python # models.py from django.db import models class A(models.Model): pass class B(models.Model): a = models.ForeignKey(A) class Meta: order_with_respect_to = 'a' }}} {{{#!python # migrations/0001_initial.py (generated on Py2) from __future__ import unicode_literals from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ ] operations = [ migrations.CreateModel( name='A', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ], options={ }, bases=(models.Model,), ), migrations.CreateModel( name='B', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('a', models.ForeignKey(to='app.A')), ], options={ }, bases=(models.Model,), ), migrations.AlterOrderWithRespectTo( name='b', order_with_respect_to=b'a', ), ] }}} It would also fail with a similar exception when migration on Python 3 {{{#!python Operations to perform: Apply all migrations: auth, app, sessions, contenttypes, migratemodule, admin Running migrations: Applying app.0001_initial...Traceback (most recent call last): File "./manage.py", line 11, in <module> execute_from_command_line(sys.argv) File "/home/simon/workspace/django/django/core/management/__init__.py", line 330, in execute_from_command_line utility.execute() File "/home/simon/workspace/django/django/core/management/__init__.py", line 322, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/simon/workspace/django/django/core/management/base.py", line 363, in run_from_argv self.execute(*args, **cmd_options) File "/home/simon/workspace/django/django/core/management/base.py", line 413, in execute output = self.handle(*args, **options) File "/home/simon/workspace/django/django/core/management/commands/migrate.py", line 160, in handle executor.migrate(targets, plan, fake=options.get("fake", False)) File "/home/simon/workspace/django/django/db/migrations/executor.py", line 63, in migrate self.apply_migration(migration, fake=fake) File "/home/simon/workspace/django/django/db/migrations/executor.py", line 91, in apply_migration if self.detect_soft_applied(migration): File "/home/simon/workspace/django/django/db/migrations/executor.py", line 135, in detect_soft_applied apps = project_state.render() File "/home/simon/workspace/django/django/db/migrations/state.py", line 67, in render model.render(self.apps) File "/home/simon/workspace/django/django/db/migrations/state.py", line 292, in render body, File "/home/simon/workspace/django/django/db/models/base.py", line 287, in __new__ new_class._prepare() File "/home/simon/workspace/django/django/db/models/base.py", line 312, in _prepare opts._prepare(cls) File "/home/simon/workspace/django/django/db/models/options.py", line 170, in _prepare self.order_with_respect_to = self.get_field(self.order_with_respect_to) File "/home/simon/workspace/django/django/db/models/options.py", line 388, in get_field raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, name)) django.db.models.fields.FieldDoesNotExist: B has no field named b'a' }}} I think that all field and model options referring to field names somehow should be converted to `six.text_type`. Idem with `dict` based options (such as `limit_choices_to`) that might be passed as `**kwargs` or string based ones that might end up as a kwarg name since `callable(**{b'key': 'value'})` isn't allowed on Python 3 (While both `bytes` and `unicode` kwarg is allowed on Python 2). Since those criteria covers most of the existing field and model options I suggest we convert all of them (during deconstruction) instead of trying to guess every possible places where this option might be referenced. This alternative might also help mitigate issues users on Python 2 creating migrations and then later trying to move to Python 3 would encounter. -- Ticket URL: <https://code.djangoproject.com/ticket/23226#comment:7> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/081.a141eac99c0bacc1cccd11ef83cb3de3%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.