MCPcopy
hub / github.com/django/django / _migrate_all_backwards

Method _migrate_all_backwards

django/db/migrations/executor.py:176–239  ·  view source on GitHub ↗

Take a list of 2-tuples of the form (migration instance, True) and unapply them in reverse order they occur in the full_plan. Since unapplying a migration requires the project state prior to that migration, Django will compute the migration states before each of the

(self, plan, full_plan, fake)

Source from the content-addressed store, hash-verified

174 return state
175
176 def _migrate_all_backwards(self, plan, full_plan, fake):
177 """
178 Take a list of 2-tuples of the form (migration instance, True) and
179 unapply them in reverse order they occur in the full_plan.
180
181 Since unapplying a migration requires the project state prior to that
182 migration, Django will compute the migration states before each of them
183 in a first run over the plan and then unapply them in a second run over
184 the plan.
185 """
186 migrations_to_run = {m[0] for m in plan}
187 # Holds all migration states prior to the migrations being unapplied
188 states = {}
189 state = self._create_project_state()
190 applied_migrations = {
191 self.loader.graph.nodes[key]
192 for key in self.loader.applied_migrations
193 if key in self.loader.graph.nodes
194 }
195 if self.progress_callback:
196 self.progress_callback("render_start")
197 for migration, _ in full_plan:
198 if not migrations_to_run:
199 # We remove every migration that we applied from this set so
200 # that we can bail out once the last migration has been applied
201 # and don't always run until the very end of the migration
202 # process.
203 break
204 if migration in migrations_to_run:
205 if "apps" not in state.__dict__:
206 state.apps # Render all -- performance critical
207 # The state before this migration
208 states[migration] = state
209 # The old state keeps as-is, we continue with the new state
210 state = migration.mutate_state(state, preserve=True)
211 migrations_to_run.remove(migration)
212 elif migration in applied_migrations:
213 # Only mutate the state if the migration is actually applied
214 # to make sure the resulting state doesn't include changes
215 # from unrelated migrations.
216 migration.mutate_state(state, preserve=False)
217 if self.progress_callback:
218 self.progress_callback("render_success")
219
220 for migration, _ in plan:
221 self.unapply_migration(states[migration], migration, fake=fake)
222 applied_migrations.remove(migration)
223
224 # Generate the post migration state by starting from the state before
225 # the last migration is unapplied and mutating it to include all the
226 # remaining applied migrations.
227 last_unapplied_migration = plan[-1][0]
228 state = states[last_unapplied_migration]
229 # Avoid mutating state with apps rendered as it's an expensive
230 # operation.
231 del state.apps
232 for index, (migration, _) in enumerate(full_plan):
233 if migration == last_unapplied_migration:

Callers 1

migrateMethod · 0.95

Calls 4

_create_project_stateMethod · 0.95
unapply_migrationMethod · 0.95
mutate_stateMethod · 0.80
removeMethod · 0.45

Tested by

no test coverage detected