summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorCarl Meyer <carl@oddbird.net>2014-11-17 10:13:47 -0700
committerCarl Meyer <carl@oddbird.net>2014-11-19 16:11:44 -0700
commitab2819aa7b09d36d9ff24830a9825aa52b87fdb4 (patch)
treed777e7da6e47f79a75fd4c56262a0bd6811b942f /django
parente7b9a58b081299b30f807d5c66f7a5d1940efe4c (diff)
Fixed #23410 -- Avoided unnecessary rollbacks in related apps when migrating backwards.
Diffstat (limited to 'django')
-rw-r--r--django/db/migrations/executor.py17
1 files changed, 11 insertions, 6 deletions
diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py
index 32aa82b82c..f5811bb795 100644
--- a/django/db/migrations/executor.py
+++ b/django/db/migrations/executor.py
@@ -36,12 +36,17 @@ class MigrationExecutor(object):
# If the migration is already applied, do backwards mode,
# otherwise do forwards mode.
elif target in applied:
- 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:
+ # Don't migrate backwards all the way to the target node (that
+ # may roll back dependencies in other apps that don't need to
+ # be rolled back); instead roll back through target's immediate
+ # child(ren) in the same app, and no further.
+ next_in_app = sorted(
+ n for n in
+ self.loader.graph.dependents.get(target, set())
+ if n[0] == target[0]
+ )
+ for node in next_in_app:
+ for migration in self.loader.graph.backwards_plan(node):
if migration in applied:
plan.append((self.loader.graph.nodes[migration], True))
applied.remove(migration)