[Django] #27274: KeyError when using RenameModel in migrations that refer to an unmanaged model in another app.

32 views
Skip to first unread message

Django

unread,
Sep 26, 2016, 7:40:53 AM9/26/16
to django-...@googlegroups.com
#27274: KeyError when using RenameModel in migrations that refer to an unmanaged
model in another app.
-------------------------------+--------------------
Reporter: Dennis Ahrens | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------
While upgrading from django 1.9 to django 1.10 i've encountered an
KeyError (see below) when running `python manage.py migrate`.

Inside of `RenameModel.state_forwards()` the ProjectState is not aware of
the unmanaged model included in another app and dies with the KeyError:

{{{
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/core/management/__init__.py", line 367, in
execute_from_command_line
utility.execute()
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/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/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/core/management/base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/core/management/base.py", line 345, in execute
output = self.handle(*args, **options)
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/core/management/commands/migrate.py", line 163, in
handle
pre_migrate_state =
executor._create_project_state(with_applied_migrations=True)
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/db/migrations/executor.py", line 81, in
_create_project_state
migration.mutate_state(state, preserve=False)
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/db/migrations/migration.py", line 92, in
mutate_state
operation.state_forwards(self.app_label, new_state)
File "/home/ahrensde/Projects/fk_to_unmanaged_model/venv/lib/python3.5
/site-packages/django/db/migrations/operations/models.py", line 323, in
state_forwards
for name, field in state.models[related_key].fields:
KeyError: ('legacy', 'legacymodel')
}}}

To reproduce the issue i've created a project containing two apps `legacy`
and `directed`; you can find the setup on github here:
https://github.com/dahrens/django_renamemodel_related_to_unmanaged_model

`legacy` does not use migrations at all and the models are unmanaged.

models.py might look like that:

{{{
from django.db import models

class LegacyModel(models.Model):
name = models.CharField(max_length=200)

class Meta:
managed = False
db_table = 'legacy_model'
}}}

The corresponding SQL statement to create the table like that:

{{{
CREATE table legacy_model (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name character varying(50) NOT NULL
);
}}}

The direct app uses migrations and `models.py` that finally looks like
that:

{{{
from django.db import models

class RenamedDirectedModel(models.Model):
name = models.CharField(max_length=10)
legacy = models.ForeignKey("legacy.LegacyModel",
on_delete=models.CASCADE)
}}}

Additionally there are two migrations.

0001_initial.py:
{{{
# -*- coding: utf-8 -*-
# Generated by Django 1.9.9 on 2016-09-26 09:17
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('legacy', '__first__'),
]

operations = [
migrations.CreateModel(
name='DirectedModel',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=10)),
('legacy',
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
to='legacy.LegacyModel')),
],
),
]
}}}

and then 0002_auto_20160926_1023.py:

{{{
# -*- coding: utf-8 -*-
# Generated by Django 1.10.1 on 2016-09-26 10:23
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('directed', '0001_initial'),
]

operations = [
migrations.RenameModel(
old_name='DirectedModel',
new_name='RenamedDirectedModel',
),
]
}}}

Using the sample you can reproduce the bug with django version >= 1.10 -
everything below works fine. While debugging i tracked down, that the
issue is related to this commit:
https://github.com/django/django/commit/f1e408ff40d2c1753f92515c70a44634b4d47467

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

Django

unread,
Sep 26, 2016, 10:56:00 AM9/26/16
to django-...@googlegroups.com
#27274: KeyError when using RenameModel in migrations that refer to an unmanaged
model in another app.
-------------------------------+--------------------------------------

Reporter: Dennis Ahrens | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.10
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

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

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

I think the problem is mixing apps with and without migrations. You should
have migrations for `legacy`, even if the models aren't managed. After I
added and applied migrations for `legacy` (with Django 1.9.x), I had no
trouble running migrations on 1.10.

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

Django

unread,
Sep 27, 2016, 5:31:17 AM9/27/16
to django-...@googlegroups.com
#27274: KeyError when using RenameModel in migrations that refer to an unmanaged
model in another app.
-------------------------------+--------------------------------------

Reporter: Dennis Ahrens | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.10
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage: Unreviewed

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

Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Changes (by Dennis Ahrens):

* status: new => closed
* resolution: => invalid


Comment:

Thank you for the reply. You are totally right - having migrations in the
legacy app solves the issue. It feels a little scary to have migrations
for a schema, where django should __not__ do anything with SQL, but on the
other hand it perfectly makes sense, that django needs information about
those migrations, if another app relies on this information within its
migrations.

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

Reply all
Reply to author
Forward
0 new messages