MCPcopy
hub / github.com/django/django / build_graph

Method build_graph

django/db/migrations/loader.py:274–342  ·  view source on GitHub ↗

Build a migration dependency graph using both the disk and database. You'll need to rebuild the graph if you apply migrations. This isn't usually a problem as generally migration stuff runs in a one-shot process.

(self)

Source from the content-addressed store, hash-verified

272 self.replacements_progress[migration_key] = True
273
274 def build_graph(self):
275 """
276 Build a migration dependency graph using both the disk and database.
277 You'll need to rebuild the graph if you apply migrations. This isn't
278 usually a problem as generally migration stuff runs in a one-shot
279 process.
280 """
281 # Load disk data
282 self.load_disk()
283 # Load database data
284 if self.connection is None:
285 self.applied_migrations = {}
286 else:
287 recorder = MigrationRecorder(self.connection)
288 self.applied_migrations = recorder.applied_migrations()
289 # To start, populate the migration graph with nodes for ALL migrations
290 # and their dependencies. Also make note of replacing migrations at
291 # this step.
292 self.graph = MigrationGraph()
293 self.replacements = {}
294 for key, migration in self.disk_migrations.items():
295 self.graph.add_node(key, migration)
296 # Replacing migrations.
297 if migration.replaces:
298 self.replacements[key] = migration
299 for key, migration in self.disk_migrations.items():
300 # Internal (same app) dependencies.
301 self.add_internal_dependencies(key, migration)
302 # Add external dependencies now that the internal ones have been
303 # resolved.
304 for key, migration in self.disk_migrations.items():
305 self.add_external_dependencies(key, migration)
306 # Carry out replacements where possible and if enabled.
307 if self.replace_migrations:
308 self.replacements_progress = {}
309 for migration_key in self.replacements.keys():
310 self.replace_migration(migration_key)
311 # Ensure the graph is consistent.
312 try:
313 self.graph.validate_consistency()
314 except NodeNotFoundError as exc:
315 # Check if the missing node could have been replaced by any squash
316 # migration but wasn't because the squash migration was partially
317 # applied before. In that case raise a more understandable
318 # exception (#23556).
319 # Get reverse replacements.
320 reverse_replacements = {}
321 for key, migration in self.replacements.items():
322 for replaced in migration.replaces:
323 reverse_replacements.setdefault(replaced, set()).add(key)
324 # Try to reraise exception with more detail.
325 if exc.node in reverse_replacements:
326 candidates = reverse_replacements.get(exc.node, set())
327 is_replaced = any(
328 candidate in self.graph.nodes for candidate in candidates
329 )
330 if not is_replaced:
331 tries = ", ".join("%s.%s" % c for c in candidates)

Calls 15

load_diskMethod · 0.95
applied_migrationsMethod · 0.95
replace_migrationMethod · 0.95
MigrationRecorderClass · 0.90
MigrationGraphClass · 0.90
NodeNotFoundErrorClass · 0.85
add_nodeMethod · 0.80
validate_consistencyMethod · 0.80
ensure_not_cyclicMethod · 0.80
itemsMethod · 0.45