From fd061b6591ddc0b3045661ff22243919a7c76f17 Mon Sep 17 00:00:00 2001 From: twidi Date: Thu, 30 Oct 2014 16:55:38 +0100 Subject: [PATCH] Fixed #23733 -- Fixed squashing migrations that depend on multiple apps. --- django/db/migrations/loader.py | 11 ++++++++-- tests/migrations/test_loader.py | 21 +++++++++++++++++++ .../__init__.py | 0 .../app1/1_auto.py | 11 ++++++++++ .../app1/2_auto.py | 13 ++++++++++++ .../app1/2_squashed_3.py | 18 ++++++++++++++++ .../app1/3_auto.py | 13 ++++++++++++ .../app1/4_auto.py | 13 ++++++++++++ .../app1/__init__.py | 0 .../app2/1_auto.py | 13 ++++++++++++ .../app2/1_squashed_2.py | 18 ++++++++++++++++ .../app2/2_auto.py | 13 ++++++++++++ .../app2/__init__.py | 0 13 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/__init__.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app1/__init__.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py create mode 100644 tests/migrations/test_migrations_squashed_complex_multi_apps/app2/__init__.py diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 245879f83b..5d62e2fb10 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -221,8 +221,15 @@ class MigrationLoader(object): for child_key in reverse_dependencies.get(replaced, set()): if child_key in migration.replaces: continue - normal[child_key].dependencies.remove(replaced) - normal[child_key].dependencies.append(key) + # child_key may appear in a replacement + if child_key in reverse_replacements: + for replaced_child_key in reverse_replacements[child_key]: + if replaced in replacing[replaced_child_key].dependencies: + replacing[replaced_child_key].dependencies.remove(replaced) + replacing[replaced_child_key].dependencies.append(key) + else: + normal[child_key].dependencies.remove(replaced) + normal[child_key].dependencies.append(key) normal[key] = migration # Mark the replacement as applied if all its replaced ones are if all(applied_statuses): diff --git a/tests/migrations/test_loader.py b/tests/migrations/test_loader.py index a921321525..4416a86bc9 100644 --- a/tests/migrations/test_loader.py +++ b/tests/migrations/test_loader.py @@ -239,6 +239,27 @@ class LoaderTests(TestCase): recorder.flush() + @override_settings(MIGRATION_MODULES={ + "app1": "migrations.test_migrations_squashed_complex_multi_apps.app1", + "app2": "migrations.test_migrations_squashed_complex_multi_apps.app2", + }) + @modify_settings(INSTALLED_APPS={'append': [ + "migrations.test_migrations_squashed_complex_multi_apps.app1", + "migrations.test_migrations_squashed_complex_multi_apps.app2", + ]}) + def test_loading_squashed_complex_multi_apps(self): + loader = MigrationLoader(connection) + loader.build_graph() + + plan = set(loader.graph.forwards_plan(('app1', '4_auto'))) + expected_plan = set([ + ('app1', '4_auto'), + ('app1', '2_squashed_3'), + ('app2', '1_squashed_2'), + ('app1', '1_auto') + ]) + self.assertEqual(plan, expected_plan) + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed_erroneous"}) def test_loading_squashed_erroneous(self): "Tests loading a complex but erroneous set of squashed migrations" diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/__init__.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py new file mode 100644 index 0000000000..25edcfa290 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/1_auto.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py new file mode 100644 index 0000000000..dcd67ca101 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("app1", "1_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py new file mode 100644 index 0000000000..d74691fe44 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/2_squashed_3.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + replaces = [ + ("app1", "2_auto"), + ("app1", "3_auto"), + ] + + dependencies = [("app1", "1_auto"), ("app2", "2_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py new file mode 100644 index 0000000000..f2b64db833 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/3_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("app1", "2_auto"), ("app2", "2_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py new file mode 100644 index 0000000000..fa36f18566 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/4_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("app1", "3_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/__init__.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py new file mode 100644 index 0000000000..dcd67ca101 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("app1", "1_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py new file mode 100644 index 0000000000..fcd43bd0c6 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/1_squashed_2.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + replaces = [ + ("app2", "1_auto"), + ("app2", "2_auto"), + ] + + dependencies = [("app1", "1_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py new file mode 100644 index 0000000000..9743fc92a2 --- /dev/null +++ b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/2_auto.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [("app2", "1_auto")] + + operations = [ + migrations.RunPython(lambda apps, schema_editor: None) + ] diff --git a/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/__init__.py b/tests/migrations/test_migrations_squashed_complex_multi_apps/app2/__init__.py new file mode 100644 index 0000000000..e69de29bb2