Fixed #24900 -- Allowed migrating backward to squashed migrations.

This commit is contained in:
Jacob Walls 2021-06-05 01:06:17 -04:00 committed by Mariusz Felisiak
parent 9e17cc062c
commit 3219dd3388
3 changed files with 46 additions and 0 deletions

View File

@ -40,6 +40,15 @@ class MigrationExecutor:
# 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:
# If the target is missing, it's likely a replaced migration.
# Reload the graph without replacements.
if (
self.loader.replace_migrations and
target not in self.loader.graph.node_map
):
self.loader.replace_migrations = False
self.loader.build_graph()
return self.migration_plan(targets, clean_start=clean_start)
# Don't migrate backwards all the way to the target node (that # Don't migrate backwards all the way to the target node (that
# may roll back dependencies in other apps that don't need to # may roll back dependencies in other apps that don't need to
# be rolled back); instead roll back through target's immediate # be rolled back); instead roll back through target's immediate

View File

@ -980,6 +980,19 @@ class MigrateTests(MigrationTestBase):
# Unmigrate everything. # Unmigrate everything.
call_command('migrate', 'migrations', 'zero', verbosity=0) call_command('migrate', 'migrations', 'zero', verbosity=0)
@override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_migrations_squashed'})
def test_migrate_backward_to_squashed_migration(self):
try:
call_command('migrate', 'migrations', '0001_squashed_0002', verbosity=0)
self.assertTableExists('migrations_author')
self.assertTableExists('migrations_book')
call_command('migrate', 'migrations', '0001_initial', verbosity=0)
self.assertTableExists('migrations_author')
self.assertTableNotExists('migrations_book')
finally:
# Unmigrate everything.
call_command('migrate', 'migrations', 'zero', verbosity=0)
@override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_migrations'}) @override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_migrations'})
def test_migrate_inconsistent_history(self): def test_migrate_inconsistent_history(self):
""" """

View File

@ -104,6 +104,29 @@ class ExecutorTests(MigrationTestBase):
self.assertTableNotExists("migrations_author") self.assertTableNotExists("migrations_author")
self.assertTableNotExists("migrations_book") self.assertTableNotExists("migrations_book")
@override_settings(
MIGRATION_MODULES={'migrations': 'migrations.test_migrations_squashed'},
)
def test_migrate_backward_to_squashed_migration(self):
executor = MigrationExecutor(connection)
try:
self.assertTableNotExists('migrations_author')
self.assertTableNotExists('migrations_book')
executor.migrate([('migrations', '0001_squashed_0002')])
self.assertTableExists('migrations_author')
self.assertTableExists('migrations_book')
executor.loader.build_graph()
# Migrate backward to a squashed migration.
executor.migrate([('migrations', '0001_initial')])
self.assertTableExists('migrations_author')
self.assertTableNotExists('migrations_book')
finally:
# Unmigrate everything.
executor = MigrationExecutor(connection)
executor.migrate([('migrations', None)])
self.assertTableNotExists('migrations_author')
self.assertTableNotExists('migrations_book')
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_non_atomic"}) @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_non_atomic"})
def test_non_atomic_migration(self): def test_non_atomic_migration(self):
""" """
@ -733,6 +756,7 @@ class FakeLoader:
def __init__(self, graph, applied): def __init__(self, graph, applied):
self.graph = graph self.graph = graph
self.applied_migrations = applied self.applied_migrations = applied
self.replace_migrations = True
class FakeMigration: class FakeMigration: