Opened 8 years ago
Closed 8 years ago
#27274 closed Bug (invalid)
KeyError when using RenameModel in migrations that refer to an unmanaged model in another app.
Reported by: | Dennis Ahrens | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.10 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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
Change History (2)
comment:1 by , 8 years ago
comment:2 by , 8 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
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.
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 forlegacy
(with Django 1.9.x), I had no trouble running migrations on 1.10.