MCPcopy
hub / github.com/django/django / MigrationExecutor

Class MigrationExecutor

django/db/migrations/executor.py:10–413  ·  view source on GitHub ↗

End-to-end migration execution - load migrations and run them up or down to a specified set of targets.

Source from the content-addressed store, hash-verified

8
9
10class MigrationExecutor:
11 """
12 End-to-end migration execution - load migrations and run them up or down
13 to a specified set of targets.
14 """
15
16 def __init__(self, connection, progress_callback=None):
17 self.connection = connection
18 self.loader = MigrationLoader(self.connection)
19 self.recorder = MigrationRecorder(self.connection)
20 self.progress_callback = progress_callback
21
22 def migration_plan(self, targets, clean_start=False):
23 """
24 Given a set of targets, return a list of (Migration instance,
25 backwards?).
26 """
27 plan = []
28 if clean_start:
29 applied = {}
30 else:
31 applied = dict(self.loader.applied_migrations)
32 for target in targets:
33 # If the target is (app_label, None), that means unmigrate
34 # everything
35 if target[1] is None:
36 for root in self.loader.graph.root_nodes():
37 if root[0] == target[0]:
38 for migration in self.loader.graph.backwards_plan(root):
39 if migration in applied:
40 plan.append((self.loader.graph.nodes[migration], True))
41 applied.pop(migration)
42 # If the target is missing, it's likely a replaced migration.
43 # Reload the graph without replacements.
44 elif (
45 self.loader.replace_migrations
46 and target not in self.loader.graph.node_map
47 ):
48 self.loader.replace_migrations = False
49 self.loader.build_graph()
50 return self.migration_plan(targets, clean_start=clean_start)
51 # If the migration is already applied, do backwards mode,
52 # otherwise do forwards mode.
53 elif target in applied:
54 # Don't migrate backwards all the way to the target node (that
55 # may roll back dependencies in other apps that don't need to
56 # be rolled back); instead roll back through target's immediate
57 # child(ren) in the same app, and no further.
58 next_in_app = sorted(
59 n
60 for n in self.loader.graph.node_map[target].children
61 if n[0] == target[0]
62 )
63 for node in next_in_app:
64 for migration in self.loader.graph.backwards_plan(node):
65 if migration in applied:
66 plan.append((self.loader.graph.nodes[migration], True))
67 applied.pop(migration)

Calls

no outgoing calls