Fixed #23093: soft application detection for swapped models
This commit is contained in:
parent
f44dbf74a4
commit
a64bc3df77
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
from django.apps.registry import apps as global_apps
|
||||||
from .loader import MigrationLoader
|
from .loader import MigrationLoader
|
||||||
from .recorder import MigrationRecorder
|
from .recorder import MigrationRecorder
|
||||||
|
|
||||||
|
@ -136,6 +137,10 @@ class MigrationExecutor(object):
|
||||||
for operation in migration.operations:
|
for operation in migration.operations:
|
||||||
if isinstance(operation, migrations.CreateModel):
|
if isinstance(operation, migrations.CreateModel):
|
||||||
model = apps.get_model(migration.app_label, operation.name)
|
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()):
|
if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()):
|
||||||
return False
|
return False
|
||||||
found_create_migration = True
|
found_create_migration = True
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.db.migrations.executor import MigrationExecutor
|
from django.db.migrations.executor import MigrationExecutor
|
||||||
from django.test import modify_settings, override_settings
|
from django.test import modify_settings, override_settings
|
||||||
|
from django.apps.registry import apps as global_apps
|
||||||
|
|
||||||
from .test_base import MigrationTestBase
|
from .test_base import MigrationTestBase
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ class ExecutorTests(MigrationTestBase):
|
||||||
test failures first, as they may be propagating into here.
|
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"})
|
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
|
@ -193,7 +194,10 @@ class ExecutorTests(MigrationTestBase):
|
||||||
self.assertTableNotExists("migrations_tribble")
|
self.assertTableNotExists("migrations_tribble")
|
||||||
|
|
||||||
@override_settings(
|
@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",
|
AUTH_USER_MODEL="migrations.Author",
|
||||||
)
|
)
|
||||||
def test_custom_user(self):
|
def test_custom_user(self):
|
||||||
|
@ -208,6 +212,20 @@ class ExecutorTests(MigrationTestBase):
|
||||||
executor.migrate([("migrations", "0001_initial")])
|
executor.migrate([("migrations", "0001_initial")])
|
||||||
self.assertTableExists("migrations_author")
|
self.assertTableExists("migrations_author")
|
||||||
self.assertTableExists("migrations_tribble")
|
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
|
# And migrate back to clean up the database
|
||||||
executor.loader.build_graph()
|
executor.loader.build_graph()
|
||||||
executor.migrate([("migrations", None)])
|
executor.migrate([("migrations", None)])
|
||||||
|
|
Loading…
Reference in New Issue