Loading django/db/migrations/executor.py +5 −0 Original line number Diff line number Diff line from __future__ import unicode_literals from django.db import migrations from django.apps.registry import apps as global_apps from .loader import MigrationLoader from .recorder import MigrationRecorder Loading Loading @@ -136,6 +137,10 @@ class MigrationExecutor(object): for operation in migration.operations: if isinstance(operation, migrations.CreateModel): model = apps.get_model(migration.app_label, operation.name) if model._meta.swapped: # We have to fetch the model to test with from the # main app cache, as it's not a direct dependency. model = global_apps.get_model(model._meta.swapped) if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()): return False found_create_migration = True Loading tests/migrations/test_executor.py +20 −2 Original line number Diff line number Diff line from django.db import connection from django.db.migrations.executor import MigrationExecutor from django.test import modify_settings, override_settings from django.apps.registry import apps as global_apps from .test_base import MigrationTestBase Loading @@ -14,7 +15,7 @@ class ExecutorTests(MigrationTestBase): test failures first, as they may be propagating into here. """ available_apps = ["migrations", "migrations2"] available_apps = ["migrations", "migrations2", "django.contrib.auth", "django.contrib.contenttypes"] @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) def test_run(self): Loading Loading @@ -193,7 +194,10 @@ class ExecutorTests(MigrationTestBase): self.assertTableNotExists("migrations_tribble") @override_settings( MIGRATION_MODULES={"migrations": "migrations.test_migrations_custom_user"}, MIGRATION_MODULES={ "migrations": "migrations.test_migrations_custom_user", "django.contrib.auth": "django.contrib.auth.migrations", }, AUTH_USER_MODEL="migrations.Author", ) def test_custom_user(self): Loading @@ -208,6 +212,20 @@ class ExecutorTests(MigrationTestBase): executor.migrate([("migrations", "0001_initial")]) self.assertTableExists("migrations_author") self.assertTableExists("migrations_tribble") # Make sure the soft-application detection works (#23093) # Change get_table_list to not return auth_user during this as # it wouldn't be there in a normal run, and ensure migrations.Author # exists in the global app registry temporarily. old_get_table_list = connection.introspection.get_table_list connection.introspection.get_table_list = lambda c: [x for x in old_get_table_list(c) if x != "auth_user"] migrations_apps = executor.loader.project_state(("migrations", "0001_initial")).render() global_apps.get_app_config("migrations").models["author"] = migrations_apps.get_model("migrations", "author") try: migration = executor.loader.get_migration("auth", "0001_initial") self.assertEqual(executor.detect_soft_applied(migration), True) finally: connection.introspection.get_table_list = old_get_table_list del global_apps.get_app_config("migrations").models["author"] # And migrate back to clean up the database executor.loader.build_graph() executor.migrate([("migrations", None)]) Loading Loading
django/db/migrations/executor.py +5 −0 Original line number Diff line number Diff line from __future__ import unicode_literals from django.db import migrations from django.apps.registry import apps as global_apps from .loader import MigrationLoader from .recorder import MigrationRecorder Loading Loading @@ -136,6 +137,10 @@ class MigrationExecutor(object): for operation in migration.operations: if isinstance(operation, migrations.CreateModel): model = apps.get_model(migration.app_label, operation.name) if model._meta.swapped: # We have to fetch the model to test with from the # main app cache, as it's not a direct dependency. model = global_apps.get_model(model._meta.swapped) if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()): return False found_create_migration = True Loading
tests/migrations/test_executor.py +20 −2 Original line number Diff line number Diff line from django.db import connection from django.db.migrations.executor import MigrationExecutor from django.test import modify_settings, override_settings from django.apps.registry import apps as global_apps from .test_base import MigrationTestBase Loading @@ -14,7 +15,7 @@ class ExecutorTests(MigrationTestBase): test failures first, as they may be propagating into here. """ available_apps = ["migrations", "migrations2"] available_apps = ["migrations", "migrations2", "django.contrib.auth", "django.contrib.contenttypes"] @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) def test_run(self): Loading Loading @@ -193,7 +194,10 @@ class ExecutorTests(MigrationTestBase): self.assertTableNotExists("migrations_tribble") @override_settings( MIGRATION_MODULES={"migrations": "migrations.test_migrations_custom_user"}, MIGRATION_MODULES={ "migrations": "migrations.test_migrations_custom_user", "django.contrib.auth": "django.contrib.auth.migrations", }, AUTH_USER_MODEL="migrations.Author", ) def test_custom_user(self): Loading @@ -208,6 +212,20 @@ class ExecutorTests(MigrationTestBase): executor.migrate([("migrations", "0001_initial")]) self.assertTableExists("migrations_author") self.assertTableExists("migrations_tribble") # Make sure the soft-application detection works (#23093) # Change get_table_list to not return auth_user during this as # it wouldn't be there in a normal run, and ensure migrations.Author # exists in the global app registry temporarily. old_get_table_list = connection.introspection.get_table_list connection.introspection.get_table_list = lambda c: [x for x in old_get_table_list(c) if x != "auth_user"] migrations_apps = executor.loader.project_state(("migrations", "0001_initial")).render() global_apps.get_app_config("migrations").models["author"] = migrations_apps.get_model("migrations", "author") try: migration = executor.loader.get_migration("auth", "0001_initial") self.assertEqual(executor.detect_soft_applied(migration), True) finally: connection.introspection.get_table_list = old_get_table_list del global_apps.get_app_config("migrations").models["author"] # And migrate back to clean up the database executor.loader.build_graph() executor.migrate([("migrations", None)]) Loading