Fix weird planning issues when already fully migrated.
This commit is contained in:
parent
b4c493ecd3
commit
b61b634628
|
@ -33,7 +33,12 @@ class MigrationExecutor(object):
|
||||||
# If the migration is already applied, do backwards mode,
|
# If the migration is already applied, do backwards mode,
|
||||||
# otherwise do forwards mode.
|
# otherwise do forwards mode.
|
||||||
elif target in applied:
|
elif target in applied:
|
||||||
for migration in self.loader.graph.backwards_plan(target)[:-1]:
|
backwards_plan = self.loader.graph.backwards_plan(target)[:-1]
|
||||||
|
# We only do this if the migration is not the most recent one
|
||||||
|
# in its app - that is, another migration with the same app
|
||||||
|
# label is in the backwards plan
|
||||||
|
if any(node[0] == target[0] for node in backwards_plan):
|
||||||
|
for migration in backwards_plan:
|
||||||
if migration in applied:
|
if migration in applied:
|
||||||
plan.append((self.loader.graph.nodes[migration], True))
|
plan.append((self.loader.graph.nodes[migration], True))
|
||||||
applied.remove(migration)
|
applied.remove(migration)
|
||||||
|
|
|
@ -12,7 +12,7 @@ class ExecutorTests(TransactionTestCase):
|
||||||
test failures first, as they may be propagating into here.
|
test failures first, as they may be propagating into here.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
available_apps = ["migrations"]
|
available_apps = ["migrations", "django.contrib.sessions"]
|
||||||
|
|
||||||
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
|
@ -38,3 +38,35 @@ class ExecutorTests(TransactionTestCase):
|
||||||
# Are the tables there now?
|
# Are the tables there now?
|
||||||
self.assertIn("migrations_author", connection.introspection.get_table_list(connection.cursor()))
|
self.assertIn("migrations_author", connection.introspection.get_table_list(connection.cursor()))
|
||||||
self.assertIn("migrations_book", connection.introspection.get_table_list(connection.cursor()))
|
self.assertIn("migrations_book", connection.introspection.get_table_list(connection.cursor()))
|
||||||
|
|
||||||
|
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations", "sessions": "migrations.test_migrations_2"})
|
||||||
|
def test_empty_plan(self):
|
||||||
|
"""
|
||||||
|
Tests that re-planning a full migration of a fully-migrated set doesn't
|
||||||
|
perform spurious unmigrations and remigrations.
|
||||||
|
|
||||||
|
There was previously a bug where the executor just always performed the
|
||||||
|
backwards plan for applied migrations - which even for the most recent
|
||||||
|
migration in an app, might include other, dependent apps, and these
|
||||||
|
were being unmigrated.
|
||||||
|
"""
|
||||||
|
# Make the initial plan, check it
|
||||||
|
# We use 'sessions' here as the second app as it's always present
|
||||||
|
# in INSTALLED_APPS, so we can happily assign it test migrations.
|
||||||
|
executor = MigrationExecutor(connection)
|
||||||
|
plan = executor.migration_plan([("migrations", "0002_second"), ("sessions", "0001_initial")])
|
||||||
|
self.assertEqual(
|
||||||
|
plan,
|
||||||
|
[
|
||||||
|
(executor.loader.graph.nodes["migrations", "0001_initial"], False),
|
||||||
|
(executor.loader.graph.nodes["migrations", "0002_second"], False),
|
||||||
|
(executor.loader.graph.nodes["sessions", "0001_initial"], False),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
# Fake-apply all migrations
|
||||||
|
executor.migrate([("migrations", "0002_second"), ("sessions", "0001_initial")], fake=True)
|
||||||
|
# Now plan a second time and make sure it's empty
|
||||||
|
plan = executor.migration_plan([("migrations", "0002_second"), ("sessions", "0001_initial")])
|
||||||
|
self.assertEqual(plan, [])
|
||||||
|
# Erase all the fake records
|
||||||
|
executor.recorder.flush()
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [("migrations", "0002_second")]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
|
||||||
|
migrations.CreateModel(
|
||||||
|
"OtherAuthor",
|
||||||
|
[
|
||||||
|
("id", models.AutoField(primary_key=True)),
|
||||||
|
("name", models.CharField(max_length=255)),
|
||||||
|
("slug", models.SlugField(null=True)),
|
||||||
|
("age", models.IntegerField(default=0)),
|
||||||
|
("silly_field", models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
]
|
Loading…
Reference in New Issue