mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Refs #27656 -- Updated django.db docstring verbs according to PEP 257.
This commit is contained in:
committed by
Tim Graham
parent
d6e26e5b7c
commit
60e52a047e
@@ -18,9 +18,9 @@ from .topological_sort import stable_topological_sort
|
||||
|
||||
class MigrationAutodetector:
|
||||
"""
|
||||
Takes a pair of ProjectStates, and compares them to see what the
|
||||
first would need doing to make it match the second (the second
|
||||
usually being the project's current state).
|
||||
Take a pair of ProjectStates and compare them to see what the first would
|
||||
need doing to make it match the second (the second usually being the
|
||||
project's current state).
|
||||
|
||||
Note that this naturally operates on entire projects at a time,
|
||||
as it's likely that changes interact (for example, you can't
|
||||
@@ -38,7 +38,7 @@ class MigrationAutodetector:
|
||||
def changes(self, graph, trim_to_apps=None, convert_apps=None, migration_name=None):
|
||||
"""
|
||||
Main entry point to produce a list of applicable changes.
|
||||
Takes a graph to base names on and an optional set of apps
|
||||
Take a graph to base names on and an optional set of apps
|
||||
to try and restrict to (restriction is not guaranteed)
|
||||
"""
|
||||
changes = self._detect_changes(convert_apps, graph)
|
||||
@@ -90,9 +90,8 @@ class MigrationAutodetector:
|
||||
def only_relation_agnostic_fields(self, fields):
|
||||
"""
|
||||
Return a definition of the fields that ignores field names and
|
||||
what related fields actually relate to.
|
||||
Used for detecting renames (as, of course, the related fields
|
||||
change during renames)
|
||||
what related fields actually relate to. Used for detecting renames (as,
|
||||
of course, the related fields change during renames).
|
||||
"""
|
||||
fields_def = []
|
||||
for name, field in sorted(fields):
|
||||
@@ -104,7 +103,7 @@ class MigrationAutodetector:
|
||||
|
||||
def _detect_changes(self, convert_apps=None, graph=None):
|
||||
"""
|
||||
Returns a dict of migration plans which will achieve the
|
||||
Return a dict of migration plans which will achieve the
|
||||
change from from_state to to_state. The dict has app labels
|
||||
as keys and a list of migrations as values.
|
||||
|
||||
@@ -117,11 +116,10 @@ class MigrationAutodetector:
|
||||
graph is an optional argument that, if provided, can help improve
|
||||
dependency generation and avoid potential circular dependencies.
|
||||
"""
|
||||
|
||||
# The first phase is generating all the operations for each app
|
||||
# and gathering them into a big per-app list.
|
||||
# We'll then go through that list later and order it and split
|
||||
# into migrations to resolve dependencies caused by M2Ms and FKs.
|
||||
# Then go through that list, order it, and split into migrations to
|
||||
# resolve dependencies caused by M2Ms and FKs.
|
||||
self.generated_operations = {}
|
||||
self.altered_indexes = {}
|
||||
|
||||
@@ -198,9 +196,9 @@ class MigrationAutodetector:
|
||||
|
||||
def _prepare_field_lists(self):
|
||||
"""
|
||||
Prepare field lists, and prepare a list of the fields that used
|
||||
through models in the old state so we can make dependencies
|
||||
from the through model deletion to the field that uses it.
|
||||
Prepare field lists and a list of the fields that used through models
|
||||
in the old state so dependencies can be made from the through model
|
||||
deletion to the field that uses it.
|
||||
"""
|
||||
self.kept_model_keys = set(self.old_model_keys).intersection(self.new_model_keys)
|
||||
self.kept_proxy_keys = set(self.old_proxy_keys).intersection(self.new_proxy_keys)
|
||||
@@ -216,9 +214,7 @@ class MigrationAutodetector:
|
||||
self.new_field_keys.update((app_label, model_name, x) for x, y in new_model_state.fields)
|
||||
|
||||
def _generate_through_model_map(self):
|
||||
"""
|
||||
Through model map generation
|
||||
"""
|
||||
"""Through model map generation."""
|
||||
for app_label, model_name in sorted(self.old_model_keys):
|
||||
old_model_name = self.renamed_models.get((app_label, model_name), model_name)
|
||||
old_model_state = self.from_state.models[app_label, old_model_name]
|
||||
@@ -234,13 +230,13 @@ class MigrationAutodetector:
|
||||
|
||||
def _build_migration_list(self, graph=None):
|
||||
"""
|
||||
We need to chop the lists of operations up into migrations with
|
||||
dependencies on each other. We do this by stepping up an app's list of
|
||||
operations until we find one that has an outgoing dependency that isn't
|
||||
in another app's migration yet (hasn't been chopped off its list). We
|
||||
then chop off the operations before it into a migration and move onto
|
||||
the next app. If we loop back around without doing anything, there's a
|
||||
circular dependency (which _should_ be impossible as the operations are
|
||||
Chop the lists of operations up into migrations with dependencies on
|
||||
each other. Do this by going through an app's list of operations until
|
||||
one is found that has an outgoing dependency that isn't in another
|
||||
app's migration yet (hasn't been chopped off its list). Then chop off
|
||||
the operations before it into a migration and move onto the next app.
|
||||
If the loops completes without doing anything, there's a circular
|
||||
dependency (which _should_ be impossible as the operations are
|
||||
all split at this point so they can't depend and be depended on).
|
||||
"""
|
||||
self.migrations = {}
|
||||
@@ -325,9 +321,8 @@ class MigrationAutodetector:
|
||||
|
||||
def _sort_migrations(self):
|
||||
"""
|
||||
Reorder to make things possible. The order we have already isn't bad,
|
||||
but we need to pull a few things around so FKs work nicely inside the
|
||||
same app
|
||||
Reorder to make things possible. Reordering may be needed so FKs work
|
||||
nicely inside the same app.
|
||||
"""
|
||||
for app_label, ops in sorted(self.generated_operations.items()):
|
||||
# construct a dependency graph for intra-app dependencies
|
||||
@@ -360,8 +355,8 @@ class MigrationAutodetector:
|
||||
|
||||
def check_dependency(self, operation, dependency):
|
||||
"""
|
||||
Returns ``True`` if the given operation depends on the given dependency,
|
||||
``False`` otherwise.
|
||||
Return True if the given operation depends on the given dependency,
|
||||
False otherwise.
|
||||
"""
|
||||
# Created model
|
||||
if dependency[2] is None and dependency[3] is True:
|
||||
@@ -431,8 +426,8 @@ class MigrationAutodetector:
|
||||
|
||||
def swappable_first_key(self, item):
|
||||
"""
|
||||
Sorting key function that places potential swappable models first in
|
||||
lists of created models (only real way to solve #22783)
|
||||
Place potential swappable models first in lists of created models (only
|
||||
real way to solve #22783).
|
||||
"""
|
||||
try:
|
||||
model = self.new_apps.get_model(item[0], item[1])
|
||||
@@ -451,9 +446,9 @@ class MigrationAutodetector:
|
||||
|
||||
def generate_renamed_models(self):
|
||||
"""
|
||||
Finds any renamed models, and generates the operations for them,
|
||||
and removes the old entry from the model lists.
|
||||
Must be run before other model-level generation.
|
||||
Find any renamed models, generate the operations for them, and remove
|
||||
the old entry from the model lists. Must be run before other
|
||||
model-level generation.
|
||||
"""
|
||||
self.renamed_models = {}
|
||||
self.renamed_models_rel = {}
|
||||
@@ -490,11 +485,11 @@ class MigrationAutodetector:
|
||||
"""
|
||||
Find all new models (both managed and unmanaged) and make create
|
||||
operations for them as well as separate operations to create any
|
||||
foreign key or M2M relationships (we'll optimize these back in later
|
||||
if we can).
|
||||
foreign key or M2M relationships (these are optimized later, if
|
||||
possible).
|
||||
|
||||
We also defer any model options that refer to collections of fields
|
||||
that might be deferred (e.g. unique_together, index_together).
|
||||
Defer any model options that refer to collections of fields that might
|
||||
be deferred (e.g. unique_together, index_together).
|
||||
"""
|
||||
old_keys = set(self.old_model_keys).union(self.old_unmanaged_keys)
|
||||
added_models = set(self.new_model_keys) - old_keys
|
||||
@@ -643,10 +638,10 @@ class MigrationAutodetector:
|
||||
|
||||
def generate_created_proxies(self):
|
||||
"""
|
||||
Makes CreateModel statements for proxy models.
|
||||
We use the same statements as that way there's less code duplication,
|
||||
but of course for proxy models we can skip all that pointless field
|
||||
stuff and just chuck out an operation.
|
||||
Make CreateModel statements for proxy models. Use the same statements
|
||||
as that way there's less code duplication, but of course for proxy
|
||||
models it's safe to skip all the pointless field stuff and just chuck
|
||||
out an operation.
|
||||
"""
|
||||
added = set(self.new_proxy_keys) - set(self.old_proxy_keys)
|
||||
for app_label, model_name in sorted(added):
|
||||
@@ -679,10 +674,10 @@ class MigrationAutodetector:
|
||||
"""
|
||||
Find all deleted models (managed and unmanaged) and make delete
|
||||
operations for them as well as separate operations to delete any
|
||||
foreign key or M2M relationships (we'll optimize these back in later
|
||||
if we can).
|
||||
foreign key or M2M relationships (these are optimized later, if
|
||||
possible).
|
||||
|
||||
We also bring forward removal of any model options that refer to
|
||||
Also bring forward removal of any model options that refer to
|
||||
collections of fields - the inverse of generate_created_models().
|
||||
"""
|
||||
new_keys = set(self.new_model_keys).union(self.new_unmanaged_keys)
|
||||
@@ -769,9 +764,7 @@ class MigrationAutodetector:
|
||||
)
|
||||
|
||||
def generate_deleted_proxies(self):
|
||||
"""
|
||||
Makes DeleteModel statements for proxy models.
|
||||
"""
|
||||
"""Make DeleteModel options for proxy models."""
|
||||
deleted = set(self.old_proxy_keys) - set(self.new_proxy_keys)
|
||||
for app_label, model_name in sorted(deleted):
|
||||
model_state = self.from_state.models[app_label, model_name]
|
||||
@@ -784,9 +777,7 @@ class MigrationAutodetector:
|
||||
)
|
||||
|
||||
def generate_renamed_fields(self):
|
||||
"""
|
||||
Works out renamed fields
|
||||
"""
|
||||
"""Work out renamed fields."""
|
||||
self.renamed_fields = {}
|
||||
for app_label, model_name, field_name in sorted(self.new_field_keys - self.old_field_keys):
|
||||
old_model_name = self.renamed_models.get((app_label, model_name), model_name)
|
||||
@@ -817,9 +808,7 @@ class MigrationAutodetector:
|
||||
break
|
||||
|
||||
def generate_added_fields(self):
|
||||
"""
|
||||
Fields that have been added
|
||||
"""
|
||||
"""Make AddField operations."""
|
||||
for app_label, model_name, field_name in sorted(self.new_field_keys - self.old_field_keys):
|
||||
self._generate_added_field(app_label, model_name, field_name)
|
||||
|
||||
@@ -855,9 +844,7 @@ class MigrationAutodetector:
|
||||
)
|
||||
|
||||
def generate_removed_fields(self):
|
||||
"""
|
||||
Fields that have been removed.
|
||||
"""
|
||||
"""Make RemoveField operations."""
|
||||
for app_label, model_name, field_name in sorted(self.old_field_keys - self.new_field_keys):
|
||||
self._generate_removed_field(app_label, model_name, field_name)
|
||||
|
||||
@@ -879,7 +866,8 @@ class MigrationAutodetector:
|
||||
|
||||
def generate_altered_fields(self):
|
||||
"""
|
||||
Fields that have been altered.
|
||||
Make AlterField operations, or possibly RemovedField/AddField if alter
|
||||
isn's possible.
|
||||
"""
|
||||
for app_label, model_name, field_name in sorted(self.old_field_keys.intersection(self.new_field_keys)):
|
||||
# Did the field change?
|
||||
@@ -1057,9 +1045,9 @@ class MigrationAutodetector:
|
||||
|
||||
def generate_altered_options(self):
|
||||
"""
|
||||
Works out if any non-schema-affecting options have changed and
|
||||
makes an operation to represent them in state changes (in case Python
|
||||
code in migrations needs them)
|
||||
Work out if any non-schema-affecting options have changed and make an
|
||||
operation to represent them in state changes (in case Python code in
|
||||
migrations needs them).
|
||||
"""
|
||||
models_to_check = self.kept_model_keys.union(
|
||||
self.kept_proxy_keys
|
||||
@@ -1137,9 +1125,9 @@ class MigrationAutodetector:
|
||||
|
||||
def arrange_for_graph(self, changes, graph, migration_name=None):
|
||||
"""
|
||||
Takes in a result from changes() and a MigrationGraph,
|
||||
and fixes the names and dependencies of the changes so they
|
||||
extend the graph from the leaf nodes for each app.
|
||||
Take a result from changes() and a MigrationGraph, and fix the names
|
||||
and dependencies of the changes so they extend the graph from the leaf
|
||||
nodes for each app.
|
||||
"""
|
||||
leaves = graph.leaf_nodes()
|
||||
name_map = {}
|
||||
@@ -1186,11 +1174,10 @@ class MigrationAutodetector:
|
||||
|
||||
def _trim_to_apps(self, changes, app_labels):
|
||||
"""
|
||||
Takes changes from arrange_for_graph and set of app labels and
|
||||
returns a modified set of changes which trims out as many migrations
|
||||
that are not in app_labels as possible.
|
||||
Note that some other migrations may still be present, as they may be
|
||||
required dependencies.
|
||||
Take changes from arrange_for_graph() and set of app labels, and return
|
||||
a modified set of changes which trims out as many migrations that are
|
||||
not in app_labels as possible. Note that some other migrations may
|
||||
still be present as they may be required dependencies.
|
||||
"""
|
||||
# Gather other app dependencies in a first pass
|
||||
app_dependencies = {}
|
||||
@@ -1214,10 +1201,9 @@ class MigrationAutodetector:
|
||||
@classmethod
|
||||
def suggest_name(cls, ops):
|
||||
"""
|
||||
Given a set of operations, suggests a name for the migration
|
||||
they might represent. Names are not guaranteed to be unique,
|
||||
but we put some effort in to the fallback name to avoid VCS conflicts
|
||||
if we can.
|
||||
Given a set of operations, suggest a name for the migration they might
|
||||
represent. Names are not guaranteed to be unique, but put some effort
|
||||
into the fallback name to avoid VCS conflicts if possible.
|
||||
"""
|
||||
if len(ops) == 1:
|
||||
if isinstance(ops[0], operations.CreateModel):
|
||||
@@ -1236,8 +1222,8 @@ class MigrationAutodetector:
|
||||
@classmethod
|
||||
def parse_number(cls, name):
|
||||
"""
|
||||
Given a migration name, tries to extract a number from the
|
||||
beginning of it. If no number found, returns None.
|
||||
Given a migration name, try to extract a number from the beginning of
|
||||
it. If no number is found, return None.
|
||||
"""
|
||||
match = re.match(r'^\d+', name)
|
||||
if match:
|
||||
|
||||
@@ -2,51 +2,37 @@ from django.db.utils import DatabaseError
|
||||
|
||||
|
||||
class AmbiguityError(Exception):
|
||||
"""
|
||||
Raised when more than one migration matches a name prefix.
|
||||
"""
|
||||
"""More than one migration matches a name prefix."""
|
||||
pass
|
||||
|
||||
|
||||
class BadMigrationError(Exception):
|
||||
"""
|
||||
Raised when there's a bad migration (unreadable/bad format/etc.).
|
||||
"""
|
||||
"""There's a bad migration (unreadable/bad format/etc.)."""
|
||||
pass
|
||||
|
||||
|
||||
class CircularDependencyError(Exception):
|
||||
"""
|
||||
Raised when there's an impossible-to-resolve circular dependency.
|
||||
"""
|
||||
"""There's an impossible-to-resolve circular dependency."""
|
||||
pass
|
||||
|
||||
|
||||
class InconsistentMigrationHistory(Exception):
|
||||
"""
|
||||
Raised when an applied migration has some of its dependencies not applied.
|
||||
"""
|
||||
"""An applied migration has some of its dependencies not applied."""
|
||||
pass
|
||||
|
||||
|
||||
class InvalidBasesError(ValueError):
|
||||
"""
|
||||
Raised when a model's base classes can't be resolved.
|
||||
"""
|
||||
"""A model's base classes can't be resolved."""
|
||||
pass
|
||||
|
||||
|
||||
class IrreversibleError(RuntimeError):
|
||||
"""
|
||||
Raised when a irreversible migration is about to be reversed.
|
||||
"""
|
||||
"""An irreversible migration is about to be reversed."""
|
||||
pass
|
||||
|
||||
|
||||
class NodeNotFoundError(LookupError):
|
||||
"""
|
||||
Raised when an attempt on a node is made that is not available in the graph.
|
||||
"""
|
||||
"""An attempt on a node is made that is not available in the graph."""
|
||||
|
||||
def __init__(self, message, node, origin=None):
|
||||
self.message = message
|
||||
|
||||
@@ -9,8 +9,8 @@ from .state import ProjectState
|
||||
|
||||
class MigrationExecutor:
|
||||
"""
|
||||
End-to-end migration execution - loads migrations, and runs them
|
||||
up or down to a specified set of targets.
|
||||
End-to-end migration execution - load migrations and run them up or down
|
||||
to a specified set of targets.
|
||||
"""
|
||||
|
||||
def __init__(self, connection, progress_callback=None):
|
||||
@@ -21,7 +21,7 @@ class MigrationExecutor:
|
||||
|
||||
def migration_plan(self, targets, clean_start=False):
|
||||
"""
|
||||
Given a set of targets, returns a list of (Migration instance, backwards?).
|
||||
Given a set of targets, return a list of (Migration instance, backwards?).
|
||||
"""
|
||||
plan = []
|
||||
if clean_start:
|
||||
@@ -81,7 +81,7 @@ class MigrationExecutor:
|
||||
|
||||
def migrate(self, targets, plan=None, state=None, fake=False, fake_initial=False):
|
||||
"""
|
||||
Migrates the database up to the given targets.
|
||||
Migrate the database up to the given targets.
|
||||
|
||||
Django first needs to create all project states before a migration is
|
||||
(un)applied and in a second step run all the database operations.
|
||||
@@ -208,8 +208,8 @@ class MigrationExecutor:
|
||||
|
||||
def collect_sql(self, plan):
|
||||
"""
|
||||
Takes a migration plan and returns a list of collected SQL
|
||||
statements that represent the best-efforts version of that plan.
|
||||
Take a migration plan and return a list of collected SQL statements
|
||||
that represent the best-efforts version of that plan.
|
||||
"""
|
||||
statements = []
|
||||
state = None
|
||||
@@ -225,9 +225,7 @@ class MigrationExecutor:
|
||||
return statements
|
||||
|
||||
def apply_migration(self, state, migration, fake=False, fake_initial=False):
|
||||
"""
|
||||
Runs a migration forwards.
|
||||
"""
|
||||
"""Run a migration forwards."""
|
||||
if self.progress_callback:
|
||||
self.progress_callback("apply_start", migration, fake)
|
||||
if not fake:
|
||||
@@ -252,9 +250,7 @@ class MigrationExecutor:
|
||||
return state
|
||||
|
||||
def unapply_migration(self, state, migration, fake=False):
|
||||
"""
|
||||
Runs a migration backwards.
|
||||
"""
|
||||
"""Run a migration backwards."""
|
||||
if self.progress_callback:
|
||||
self.progress_callback("unapply_start", migration, fake)
|
||||
if not fake:
|
||||
@@ -275,12 +271,12 @@ class MigrationExecutor:
|
||||
"""
|
||||
Mark replacement migrations applied if their replaced set all are.
|
||||
|
||||
We do this unconditionally on every migrate, rather than just when
|
||||
migrations are applied or unapplied, so as to correctly handle the case
|
||||
Do this unconditionally on every migrate, rather than just when
|
||||
migrations are applied or unapplied, to correctly handle the case
|
||||
when a new squash migration is pushed to a deployment that already had
|
||||
all its replaced migrations applied. In this case no new migration will
|
||||
be applied, but we still want to correctly maintain the applied state
|
||||
of the squash migration.
|
||||
be applied, but the applied state of the squashed migration must be
|
||||
maintained.
|
||||
"""
|
||||
applied = self.recorder.applied_migrations()
|
||||
for key, migration in self.loader.replacements.items():
|
||||
@@ -290,7 +286,7 @@ class MigrationExecutor:
|
||||
|
||||
def detect_soft_applied(self, project_state, migration):
|
||||
"""
|
||||
Tests whether a migration has been implicitly applied - that the
|
||||
Test whether a migration has been implicitly applied - that the
|
||||
tables or columns it would create exist. This is intended only for use
|
||||
on initial migrations (as it only looks for CreateModel and AddField).
|
||||
"""
|
||||
|
||||
@@ -97,7 +97,7 @@ class DummyNode(Node):
|
||||
|
||||
class MigrationGraph:
|
||||
"""
|
||||
Represents the digraph of all migrations in a project.
|
||||
Represent the digraph of all migrations in a project.
|
||||
|
||||
Each migration is a node, and each dependency is an edge. There are
|
||||
no implicit dependencies between numbered migrations - the numbering is
|
||||
@@ -142,8 +142,9 @@ class MigrationGraph:
|
||||
|
||||
def add_dependency(self, migration, child, parent, skip_validation=False):
|
||||
"""
|
||||
This may create dummy nodes if they don't yet exist.
|
||||
If `skip_validation` is set, validate_consistency should be called afterwards.
|
||||
This may create dummy nodes if they don't yet exist. If
|
||||
`skip_validation=True`, validate_consistency() should be called
|
||||
afterwards.
|
||||
"""
|
||||
if child not in self.nodes:
|
||||
error_message = (
|
||||
@@ -165,7 +166,7 @@ class MigrationGraph:
|
||||
|
||||
def remove_replaced_nodes(self, replacement, replaced):
|
||||
"""
|
||||
Removes each of the `replaced` nodes (when they exist). Any
|
||||
Remove each of the `replaced` nodes (when they exist). Any
|
||||
dependencies that were referencing them are changed to reference the
|
||||
`replacement` node instead.
|
||||
"""
|
||||
@@ -201,10 +202,10 @@ class MigrationGraph:
|
||||
|
||||
def remove_replacement_node(self, replacement, replaced):
|
||||
"""
|
||||
The inverse operation to `remove_replaced_nodes`. Almost. Removes the
|
||||
replacement node `replacement` and remaps its child nodes to
|
||||
`replaced` - the list of nodes it would have replaced. Its parent
|
||||
nodes are not remapped as they are expected to be correct already.
|
||||
The inverse operation to `remove_replaced_nodes`. Almost. Remove the
|
||||
replacement node `replacement` and remap its child nodes to `replaced`
|
||||
- the list of nodes it would have replaced. Don't remap its parent
|
||||
nodes as they are expected to be correct already.
|
||||
"""
|
||||
self.nodes.pop(replacement, None)
|
||||
try:
|
||||
@@ -237,9 +238,7 @@ class MigrationGraph:
|
||||
self.clear_cache()
|
||||
|
||||
def validate_consistency(self):
|
||||
"""
|
||||
Ensure there are no dummy nodes remaining in the graph.
|
||||
"""
|
||||
"""Ensure there are no dummy nodes remaining in the graph."""
|
||||
[n.raise_error() for n in self.node_map.values() if isinstance(n, DummyNode)]
|
||||
|
||||
def clear_cache(self):
|
||||
@@ -251,10 +250,9 @@ class MigrationGraph:
|
||||
|
||||
def forwards_plan(self, target):
|
||||
"""
|
||||
Given a node, returns a list of which previous nodes (dependencies)
|
||||
must be applied, ending with the node itself.
|
||||
This is the list you would follow if applying the migrations to
|
||||
a database.
|
||||
Given a node, return a list of which previous nodes (dependencies) must
|
||||
be applied, ending with the node itself. This is the list you would
|
||||
follow if applying the migrations to a database.
|
||||
"""
|
||||
if target not in self.nodes:
|
||||
raise NodeNotFoundError("Node %r not a valid node" % (target, ), target)
|
||||
@@ -271,10 +269,9 @@ class MigrationGraph:
|
||||
|
||||
def backwards_plan(self, target):
|
||||
"""
|
||||
Given a node, returns a list of which dependent nodes (dependencies)
|
||||
must be unapplied, ending with the node itself.
|
||||
This is the list you would follow if removing the migrations from
|
||||
a database.
|
||||
Given a node, return a list of which dependent nodes (dependencies)
|
||||
must be unapplied, ending with the node itself. This is the list you
|
||||
would follow if removing the migrations from a database.
|
||||
"""
|
||||
if target not in self.nodes:
|
||||
raise NodeNotFoundError("Node %r not a valid node" % (target, ), target)
|
||||
@@ -290,9 +287,7 @@ class MigrationGraph:
|
||||
return self.iterative_dfs(node, forwards=False)
|
||||
|
||||
def iterative_dfs(self, start, forwards=True):
|
||||
"""
|
||||
Iterative depth first search, for finding dependencies.
|
||||
"""
|
||||
"""Iterative depth-first search for finding dependencies."""
|
||||
visited = deque()
|
||||
visited.append(start)
|
||||
if forwards:
|
||||
@@ -314,7 +309,7 @@ class MigrationGraph:
|
||||
|
||||
def root_nodes(self, app=None):
|
||||
"""
|
||||
Returns all root nodes - that is, nodes with no dependencies inside
|
||||
Return all root nodes - that is, nodes with no dependencies inside
|
||||
their app. These are the starting point for an app.
|
||||
"""
|
||||
roots = set()
|
||||
@@ -325,7 +320,7 @@ class MigrationGraph:
|
||||
|
||||
def leaf_nodes(self, app=None):
|
||||
"""
|
||||
Returns all leaf nodes - that is, nodes with no dependents in their app.
|
||||
Return all leaf nodes - that is, nodes with no dependents in their app.
|
||||
These are the "most current" version of an app's schema.
|
||||
Having more than one per app is technically an error, but one that
|
||||
gets handled further up, in the interactive command - it's usually the
|
||||
@@ -369,9 +364,9 @@ class MigrationGraph:
|
||||
|
||||
def make_state(self, nodes=None, at_end=True, real_apps=None):
|
||||
"""
|
||||
Given a migration node or nodes, returns a complete ProjectState for it.
|
||||
If at_end is False, returns the state before the migration has run.
|
||||
If nodes is not provided, returns the overall most current project state.
|
||||
Given a migration node or nodes, return a complete ProjectState for it.
|
||||
If at_end is False, return the state before the migration has run.
|
||||
If nodes is not provided, return the overall most current project state.
|
||||
"""
|
||||
if nodes is None:
|
||||
nodes = list(self.leaf_nodes())
|
||||
|
||||
@@ -17,7 +17,7 @@ MIGRATIONS_MODULE_NAME = 'migrations'
|
||||
|
||||
class MigrationLoader:
|
||||
"""
|
||||
Loads migration files from disk, and their status from the database.
|
||||
Load migration files from disk and their status from the database.
|
||||
|
||||
Migration files are expected to live in the "migrations" directory of
|
||||
an app. Their names are entirely unimportant from a code perspective,
|
||||
@@ -62,9 +62,7 @@ class MigrationLoader:
|
||||
return '%s.%s' % (app_package_name, MIGRATIONS_MODULE_NAME), False
|
||||
|
||||
def load_disk(self):
|
||||
"""
|
||||
Loads the migrations from all INSTALLED_APPS from disk.
|
||||
"""
|
||||
"""Load the migrations from all INSTALLED_APPS from disk."""
|
||||
self.disk_migrations = {}
|
||||
self.unmigrated_apps = set()
|
||||
self.migrated_apps = set()
|
||||
@@ -119,11 +117,13 @@ class MigrationLoader:
|
||||
)
|
||||
|
||||
def get_migration(self, app_label, name_prefix):
|
||||
"Gets the migration exactly named, or raises `graph.NodeNotFoundError`"
|
||||
"""Return the named migration or raise NodeNotFoundError."""
|
||||
return self.graph.nodes[app_label, name_prefix]
|
||||
|
||||
def get_migration_by_prefix(self, app_label, name_prefix):
|
||||
"Returns the migration(s) which match the given app label and name _prefix_"
|
||||
"""
|
||||
Return the migration(s) which match the given app label and name_prefix.
|
||||
"""
|
||||
# Do the search
|
||||
results = []
|
||||
for migration_app_label, migration_name in self.disk_migrations:
|
||||
@@ -192,7 +192,7 @@ class MigrationLoader:
|
||||
|
||||
def build_graph(self):
|
||||
"""
|
||||
Builds a migration dependency graph using both the disk and database.
|
||||
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.
|
||||
"""
|
||||
@@ -294,8 +294,8 @@ class MigrationLoader:
|
||||
|
||||
def detect_conflicts(self):
|
||||
"""
|
||||
Looks through the loaded graph and detects any conflicts - apps
|
||||
with more than one leaf migration. Returns a dict of the app labels
|
||||
Look through the loaded graph and detect any conflicts - apps
|
||||
with more than one leaf migration. Return a dict of the app labels
|
||||
that conflict with the migration names that conflict.
|
||||
"""
|
||||
seen_apps = {}
|
||||
@@ -308,9 +308,9 @@ class MigrationLoader:
|
||||
|
||||
def project_state(self, nodes=None, at_end=True):
|
||||
"""
|
||||
Returns a ProjectState object representing the most recent state
|
||||
that the migrations we loaded represent.
|
||||
Return a ProjectState object representing the most recent state
|
||||
that the loaded migrations represent.
|
||||
|
||||
See graph.make_state for the meaning of "nodes" and "at_end"
|
||||
See graph.make_state() for the meaning of "nodes" and "at_end".
|
||||
"""
|
||||
return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps))
|
||||
|
||||
@@ -73,9 +73,9 @@ class Migration:
|
||||
|
||||
def mutate_state(self, project_state, preserve=True):
|
||||
"""
|
||||
Takes a ProjectState and returns a new one with the migration's
|
||||
operations applied to it. Preserves the original object state by
|
||||
default and will return a mutated state from a copy.
|
||||
Take a ProjectState and return a new one with the migration's
|
||||
operations applied to it. Preserve the original object state by
|
||||
default and return a mutated state from a copy.
|
||||
"""
|
||||
new_state = project_state
|
||||
if preserve:
|
||||
@@ -87,11 +87,11 @@ class Migration:
|
||||
|
||||
def apply(self, project_state, schema_editor, collect_sql=False):
|
||||
"""
|
||||
Takes a project_state representing all migrations prior to this one
|
||||
and a schema_editor for a live database and applies the migration
|
||||
Take a project_state representing all migrations prior to this one
|
||||
and a schema_editor for a live database and apply the migration
|
||||
in a forwards order.
|
||||
|
||||
Returns the resulting project state for efficient re-use by following
|
||||
Return the resulting project state for efficient reuse by following
|
||||
Migrations.
|
||||
"""
|
||||
for operation in self.operations:
|
||||
@@ -124,8 +124,8 @@ class Migration:
|
||||
|
||||
def unapply(self, project_state, schema_editor, collect_sql=False):
|
||||
"""
|
||||
Takes a project_state representing all migrations prior to this one
|
||||
and a schema_editor for a live database and applies the migration
|
||||
Take a project_state representing all migrations prior to this one
|
||||
and a schema_editor for a live database and apply the migration
|
||||
in a reverse order.
|
||||
|
||||
The backwards migration process consists of two phases:
|
||||
@@ -185,7 +185,5 @@ class SwappableTuple(tuple):
|
||||
|
||||
|
||||
def swappable_dependency(value):
|
||||
"""
|
||||
Turns a setting value into a dependency.
|
||||
"""
|
||||
"""Turn a setting value into a dependency."""
|
||||
return SwappableTuple((value.split(".", 1)[0], "__first__"), value)
|
||||
|
||||
@@ -41,7 +41,7 @@ class Operation:
|
||||
|
||||
def deconstruct(self):
|
||||
"""
|
||||
Returns a 3-tuple of class import path (or just name if it lives
|
||||
Return a 3-tuple of class import path (or just name if it lives
|
||||
under django.db.migrations), positional arguments, and keyword
|
||||
arguments.
|
||||
"""
|
||||
@@ -53,21 +53,21 @@ class Operation:
|
||||
|
||||
def state_forwards(self, app_label, state):
|
||||
"""
|
||||
Takes the state from the previous migration, and mutates it
|
||||
Take the state from the previous migration, and mutate it
|
||||
so that it matches what this migration would perform.
|
||||
"""
|
||||
raise NotImplementedError('subclasses of Operation must provide a state_forwards() method')
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
"""
|
||||
Performs the mutation on the database schema in the normal
|
||||
Perform the mutation on the database schema in the normal
|
||||
(forwards) direction.
|
||||
"""
|
||||
raise NotImplementedError('subclasses of Operation must provide a database_forwards() method')
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
"""
|
||||
Performs the mutation on the database schema in the reverse
|
||||
Perform the mutation on the database schema in the reverse
|
||||
direction - e.g. if this were CreateModel, it would in fact
|
||||
drop the model's table.
|
||||
"""
|
||||
@@ -75,13 +75,13 @@ class Operation:
|
||||
|
||||
def describe(self):
|
||||
"""
|
||||
Outputs a brief summary of what the action does.
|
||||
Output a brief summary of what the action does.
|
||||
"""
|
||||
return "%s: %s" % (self.__class__.__name__, self._constructor_args)
|
||||
|
||||
def references_model(self, name, app_label=None):
|
||||
"""
|
||||
Returns True if there is a chance this operation references the given
|
||||
Return True if there is a chance this operation references the given
|
||||
model name (as a string), with an optional app label for accuracy.
|
||||
|
||||
Used for optimization. If in doubt, return True;
|
||||
@@ -93,7 +93,7 @@ class Operation:
|
||||
|
||||
def references_field(self, model_name, name, app_label=None):
|
||||
"""
|
||||
Returns True if there is a chance this operation references the given
|
||||
Return True if there is a chance this operation references the given
|
||||
field name, with an optional app label for accuracy.
|
||||
|
||||
Used for optimization. If in doubt, return True.
|
||||
@@ -102,7 +102,7 @@ class Operation:
|
||||
|
||||
def allow_migrate_model(self, connection_alias, model):
|
||||
"""
|
||||
Returns if we're allowed to migrate the model.
|
||||
Return wether or not a model may be migrated.
|
||||
|
||||
This is a thin wrapper around router.allow_migrate_model() that
|
||||
preemptively rejects any proxy, swapped out, or unmanaged model.
|
||||
|
||||
@@ -37,9 +37,7 @@ class FieldOperation(Operation):
|
||||
|
||||
|
||||
class AddField(FieldOperation):
|
||||
"""
|
||||
Adds a field to a model.
|
||||
"""
|
||||
"""Add a field to a model."""
|
||||
|
||||
def __init__(self, model_name, name, field, preserve_default=True):
|
||||
self.field = field
|
||||
@@ -118,9 +116,7 @@ class AddField(FieldOperation):
|
||||
|
||||
|
||||
class RemoveField(FieldOperation):
|
||||
"""
|
||||
Removes a field from a model.
|
||||
"""
|
||||
"""Remove a field from a model."""
|
||||
|
||||
def deconstruct(self):
|
||||
kwargs = {
|
||||
@@ -163,7 +159,8 @@ class RemoveField(FieldOperation):
|
||||
|
||||
class AlterField(FieldOperation):
|
||||
"""
|
||||
Alters a field's database column (e.g. null, max_length) to the provided new field
|
||||
Alter a field's database column (e.g. null, max_length) to the provided
|
||||
new field.
|
||||
"""
|
||||
|
||||
def __init__(self, model_name, name, field, preserve_default=True):
|
||||
@@ -236,9 +233,7 @@ class AlterField(FieldOperation):
|
||||
|
||||
|
||||
class RenameField(FieldOperation):
|
||||
"""
|
||||
Renames a field on the model. Might affect db_column too.
|
||||
"""
|
||||
"""Rename a field on the model. Might affect db_column too."""
|
||||
|
||||
def __init__(self, model_name, old_name, new_name):
|
||||
self.old_name = old_name
|
||||
|
||||
@@ -39,9 +39,7 @@ class ModelOperation(Operation):
|
||||
|
||||
|
||||
class CreateModel(ModelOperation):
|
||||
"""
|
||||
Create a model's table.
|
||||
"""
|
||||
"""Create a model's table."""
|
||||
|
||||
serialization_expand_args = ['fields', 'options', 'managers']
|
||||
|
||||
@@ -227,9 +225,7 @@ class CreateModel(ModelOperation):
|
||||
|
||||
|
||||
class DeleteModel(ModelOperation):
|
||||
"""
|
||||
Drops a model's table.
|
||||
"""
|
||||
"""Drop a model's table."""
|
||||
|
||||
def deconstruct(self):
|
||||
kwargs = {
|
||||
@@ -259,9 +255,7 @@ class DeleteModel(ModelOperation):
|
||||
|
||||
|
||||
class RenameModel(ModelOperation):
|
||||
"""
|
||||
Renames a model.
|
||||
"""
|
||||
"""Rename a model."""
|
||||
|
||||
def __init__(self, old_name, new_name):
|
||||
self.old_name = old_name
|
||||
@@ -423,9 +417,7 @@ class RenameModel(ModelOperation):
|
||||
|
||||
|
||||
class AlterModelTable(ModelOperation):
|
||||
"""
|
||||
Renames a model's table
|
||||
"""
|
||||
"""Rename a model's table."""
|
||||
|
||||
def __init__(self, name, table):
|
||||
self.table = table
|
||||
@@ -497,7 +489,7 @@ class FieldRelatedOptionOperation(ModelOptionOperation):
|
||||
|
||||
class AlterUniqueTogether(FieldRelatedOptionOperation):
|
||||
"""
|
||||
Changes the value of unique_together to the target one.
|
||||
Change the value of unique_together to the target one.
|
||||
Input value of unique_together must be a set of tuples.
|
||||
"""
|
||||
option_name = "unique_together"
|
||||
@@ -551,7 +543,7 @@ class AlterUniqueTogether(FieldRelatedOptionOperation):
|
||||
|
||||
class AlterIndexTogether(FieldRelatedOptionOperation):
|
||||
"""
|
||||
Changes the value of index_together to the target one.
|
||||
Change the value of index_together to the target one.
|
||||
Input value of index_together must be a set of tuples.
|
||||
"""
|
||||
option_name = "index_together"
|
||||
@@ -604,9 +596,7 @@ class AlterIndexTogether(FieldRelatedOptionOperation):
|
||||
|
||||
|
||||
class AlterOrderWithRespectTo(FieldRelatedOptionOperation):
|
||||
"""
|
||||
Represents a change with the order_with_respect_to option.
|
||||
"""
|
||||
"""Represent a change with the order_with_respect_to option."""
|
||||
|
||||
def __init__(self, name, order_with_respect_to):
|
||||
self.order_with_respect_to = order_with_respect_to
|
||||
@@ -664,7 +654,7 @@ class AlterOrderWithRespectTo(FieldRelatedOptionOperation):
|
||||
|
||||
class AlterModelOptions(ModelOptionOperation):
|
||||
"""
|
||||
Sets new model options that don't directly affect the database schema
|
||||
Set new model options that don't directly affect the database schema
|
||||
(like verbose_name, permissions, ordering). Python code in migrations
|
||||
may still need them.
|
||||
"""
|
||||
@@ -718,9 +708,7 @@ class AlterModelOptions(ModelOptionOperation):
|
||||
|
||||
|
||||
class AlterModelManagers(ModelOptionOperation):
|
||||
"""
|
||||
Alters the model's managers
|
||||
"""
|
||||
"""Alter the model's managers."""
|
||||
|
||||
serialization_expand_args = ['managers']
|
||||
|
||||
@@ -759,9 +747,7 @@ class IndexOperation(Operation):
|
||||
|
||||
|
||||
class AddIndex(IndexOperation):
|
||||
"""
|
||||
Add an index on a model.
|
||||
"""
|
||||
"""Add an index on a model."""
|
||||
|
||||
def __init__(self, model_name, index):
|
||||
self.model_name = model_name
|
||||
@@ -806,9 +792,7 @@ class AddIndex(IndexOperation):
|
||||
|
||||
|
||||
class RemoveIndex(IndexOperation):
|
||||
"""
|
||||
Remove an index from a model.
|
||||
"""
|
||||
"""Remove an index from a model."""
|
||||
|
||||
def __init__(self, model_name, name):
|
||||
self.model_name = model_name
|
||||
|
||||
@@ -5,7 +5,7 @@ from .base import Operation
|
||||
|
||||
class SeparateDatabaseAndState(Operation):
|
||||
"""
|
||||
Takes two lists of operations - ones that will be used for the database,
|
||||
Take two lists of operations - ones that will be used for the database,
|
||||
and ones that will be used for the state change. This allows operations
|
||||
that don't support state change to have it applied, or have operations
|
||||
that affect the state or not the database, or so on.
|
||||
@@ -62,9 +62,9 @@ class SeparateDatabaseAndState(Operation):
|
||||
|
||||
class RunSQL(Operation):
|
||||
"""
|
||||
Runs some raw SQL. A reverse SQL statement may be provided.
|
||||
Run some raw SQL. A reverse SQL statement may be provided.
|
||||
|
||||
Also accepts a list of operations that represent the state change effected
|
||||
Also accept a list of operations that represent the state change effected
|
||||
by this SQL change, in case it's custom column/table creation/deletion.
|
||||
"""
|
||||
noop = ''
|
||||
@@ -132,7 +132,7 @@ class RunSQL(Operation):
|
||||
|
||||
class RunPython(Operation):
|
||||
"""
|
||||
Runs Python code in a context suitable for doing versioned ORM operations.
|
||||
Run Python code in a context suitable for doing versioned ORM operations.
|
||||
"""
|
||||
|
||||
reduces_to_sql = False
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class MigrationOptimizer:
|
||||
"""
|
||||
Powers the optimization process, where you provide a list of Operations
|
||||
Power the optimization process, where you provide a list of Operations
|
||||
and you are returned a list of equal or shorter length - operations
|
||||
are merged into one if possible.
|
||||
|
||||
@@ -39,9 +39,7 @@ class MigrationOptimizer:
|
||||
operations = result
|
||||
|
||||
def optimize_inner(self, operations, app_label=None):
|
||||
"""
|
||||
Inner optimization loop.
|
||||
"""
|
||||
"""Inner optimization loop."""
|
||||
new_operations = []
|
||||
for i, operation in enumerate(operations):
|
||||
# Compare it to each operation after it
|
||||
|
||||
@@ -11,7 +11,7 @@ from .loader import MigrationLoader
|
||||
|
||||
class MigrationQuestioner:
|
||||
"""
|
||||
Gives the autodetector responses to questions it might have.
|
||||
Give the autodetector responses to questions it might have.
|
||||
This base class has a built-in noninteractive mode, but the
|
||||
interactive subclass is what the command-line arguments will use.
|
||||
"""
|
||||
@@ -22,7 +22,7 @@ class MigrationQuestioner:
|
||||
self.dry_run = dry_run
|
||||
|
||||
def ask_initial(self, app_label):
|
||||
"Should we create an initial migration for the app?"
|
||||
"""Should we create an initial migration for the app?"""
|
||||
# If it was specified on the command line, definitely true
|
||||
if app_label in self.specified_apps:
|
||||
return True
|
||||
@@ -52,29 +52,29 @@ class MigrationQuestioner:
|
||||
return not any(x.endswith(".py") for x in filenames if x != "__init__.py")
|
||||
|
||||
def ask_not_null_addition(self, field_name, model_name):
|
||||
"Adding a NOT NULL field to a model"
|
||||
"""Adding a NOT NULL field to a model."""
|
||||
# None means quit
|
||||
return None
|
||||
|
||||
def ask_not_null_alteration(self, field_name, model_name):
|
||||
"Changing a NULL field to NOT NULL"
|
||||
"""Changing a NULL field to NOT NULL."""
|
||||
# None means quit
|
||||
return None
|
||||
|
||||
def ask_rename(self, model_name, old_name, new_name, field_instance):
|
||||
"Was this field really renamed?"
|
||||
"""Was this field really renamed?"""
|
||||
return self.defaults.get("ask_rename", False)
|
||||
|
||||
def ask_rename_model(self, old_model_state, new_model_state):
|
||||
"Was this model really renamed?"
|
||||
"""Was this model really renamed?"""
|
||||
return self.defaults.get("ask_rename_model", False)
|
||||
|
||||
def ask_merge(self, app_label):
|
||||
"Do you really want to merge these migrations?"
|
||||
"""Do you really want to merge these migrations?"""
|
||||
return self.defaults.get("ask_merge", False)
|
||||
|
||||
def ask_auto_now_add_addition(self, field_name, model_name):
|
||||
"Adding an auto_now_add field to a model"
|
||||
"""Adding an auto_now_add field to a model."""
|
||||
# None means quit
|
||||
return None
|
||||
|
||||
@@ -138,7 +138,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
||||
print("Invalid input: %s" % e)
|
||||
|
||||
def ask_not_null_addition(self, field_name, model_name):
|
||||
"Adding a NOT NULL field to a model"
|
||||
"""Adding a NOT NULL field to a model."""
|
||||
if not self.dry_run:
|
||||
choice = self._choice_input(
|
||||
"You are trying to add a non-nullable field '%s' to %s without a default; "
|
||||
@@ -157,7 +157,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
||||
return None
|
||||
|
||||
def ask_not_null_alteration(self, field_name, model_name):
|
||||
"Changing a NULL field to NOT NULL"
|
||||
"""Changing a NULL field to NOT NULL."""
|
||||
if not self.dry_run:
|
||||
choice = self._choice_input(
|
||||
"You are trying to change the nullable field '%s' on %s to non-nullable "
|
||||
@@ -182,13 +182,13 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
||||
return None
|
||||
|
||||
def ask_rename(self, model_name, old_name, new_name, field_instance):
|
||||
"Was this field really renamed?"
|
||||
"""Was this field really renamed?"""
|
||||
msg = "Did you rename %s.%s to %s.%s (a %s)? [y/N]"
|
||||
return self._boolean_input(msg % (model_name, old_name, model_name, new_name,
|
||||
field_instance.__class__.__name__), False)
|
||||
|
||||
def ask_rename_model(self, old_model_state, new_model_state):
|
||||
"Was this model really renamed?"
|
||||
"""Was this model really renamed?"""
|
||||
msg = "Did you rename the %s.%s model to %s? [y/N]"
|
||||
return self._boolean_input(msg % (old_model_state.app_label, old_model_state.name,
|
||||
new_model_state.name), False)
|
||||
@@ -202,7 +202,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
||||
)
|
||||
|
||||
def ask_auto_now_add_addition(self, field_name, model_name):
|
||||
"Adding an auto_now_add field to a model"
|
||||
"""Adding an auto_now_add field to a model."""
|
||||
if not self.dry_run:
|
||||
choice = self._choice_input(
|
||||
"You are trying to add the field '{}' with 'auto_now_add=True' "
|
||||
|
||||
@@ -8,7 +8,7 @@ from .exceptions import MigrationSchemaMissing
|
||||
|
||||
class MigrationRecorder:
|
||||
"""
|
||||
Deals with storing migration records in the database.
|
||||
Deal with storing migration records in the database.
|
||||
|
||||
Because this table is actually itself used for dealing with model
|
||||
creation, it's the one thing we can't do normally via migrations.
|
||||
@@ -40,9 +40,7 @@ class MigrationRecorder:
|
||||
return self.Migration.objects.using(self.connection.alias)
|
||||
|
||||
def ensure_schema(self):
|
||||
"""
|
||||
Ensures the table exists and has the correct schema.
|
||||
"""
|
||||
"""Ensure the table exists and has the correct schema."""
|
||||
# If the table's there, that's fine - we've never changed its schema
|
||||
# in the codebase.
|
||||
if self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor()):
|
||||
@@ -55,28 +53,20 @@ class MigrationRecorder:
|
||||
raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
|
||||
|
||||
def applied_migrations(self):
|
||||
"""
|
||||
Returns a set of (app, name) of applied migrations.
|
||||
"""
|
||||
"""Return a set of (app, name) of applied migrations."""
|
||||
self.ensure_schema()
|
||||
return set(tuple(x) for x in self.migration_qs.values_list("app", "name"))
|
||||
|
||||
def record_applied(self, app, name):
|
||||
"""
|
||||
Records that a migration was applied.
|
||||
"""
|
||||
"""Record that a migration was applied."""
|
||||
self.ensure_schema()
|
||||
self.migration_qs.create(app=app, name=name)
|
||||
|
||||
def record_unapplied(self, app, name):
|
||||
"""
|
||||
Records that a migration was unapplied.
|
||||
"""
|
||||
"""Record that a migration was unapplied."""
|
||||
self.ensure_schema()
|
||||
self.migration_qs.filter(app=app, name=name).delete()
|
||||
|
||||
def flush(self):
|
||||
"""
|
||||
Deletes all migration records. Useful if you're testing migrations.
|
||||
"""
|
||||
"""Delete all migration records. Useful for testing migrations."""
|
||||
self.migration_qs.all().delete()
|
||||
|
||||
@@ -27,9 +27,7 @@ def _get_app_label_and_model_name(model, app_label=''):
|
||||
|
||||
|
||||
def _get_related_models(m):
|
||||
"""
|
||||
Return all models that have a direct relationship to the given model.
|
||||
"""
|
||||
"""Return all models that have a direct relationship to the given model."""
|
||||
related_models = [
|
||||
subclass for subclass in m.__subclasses__()
|
||||
if issubclass(subclass, models.Model)
|
||||
@@ -82,9 +80,9 @@ def get_related_models_recursive(model):
|
||||
|
||||
class ProjectState:
|
||||
"""
|
||||
Represents the entire project's overall state.
|
||||
This is the item that is passed around - we do it here rather than at the
|
||||
app level so that cross-app FKs/etc. resolve properly.
|
||||
Represent the entire project's overall state. This is the item that is
|
||||
passed around - do it here rather than at the app level so that cross-app
|
||||
FKs/etc. resolve properly.
|
||||
"""
|
||||
|
||||
def __init__(self, models=None, real_apps=None):
|
||||
@@ -194,7 +192,7 @@ class ProjectState:
|
||||
self.apps.render_multiple(states_to_be_rendered)
|
||||
|
||||
def clone(self):
|
||||
"Returns an exact copy of this ProjectState"
|
||||
"""Return an exact copy of this ProjectState."""
|
||||
new_state = ProjectState(
|
||||
models={k: v.clone() for k, v in self.models.items()},
|
||||
real_apps=self.real_apps,
|
||||
@@ -219,7 +217,7 @@ class ProjectState:
|
||||
|
||||
@classmethod
|
||||
def from_apps(cls, apps):
|
||||
"Takes in an Apps and returns a ProjectState matching it"
|
||||
"""Take an Apps and return a ProjectState matching it."""
|
||||
app_models = {}
|
||||
for model in apps.get_models(include_swapped=True):
|
||||
model_state = ModelState.from_model(model)
|
||||
@@ -235,9 +233,7 @@ class ProjectState:
|
||||
|
||||
|
||||
class AppConfigStub(AppConfig):
|
||||
"""
|
||||
Stubs a Django AppConfig. Only provides a label, and a dict of models.
|
||||
"""
|
||||
"""Stub of an AppConfig. Only provides a label and a dict of models."""
|
||||
# Not used, but required by AppConfig.__init__
|
||||
path = ''
|
||||
|
||||
@@ -325,9 +321,7 @@ class StateApps(Apps):
|
||||
unrendered_models = new_unrendered_models
|
||||
|
||||
def clone(self):
|
||||
"""
|
||||
Return a clone of this registry, mainly used by the migration framework.
|
||||
"""
|
||||
"""Return a clone of this registry."""
|
||||
clone = StateApps([], {})
|
||||
clone.all_models = copy.deepcopy(self.all_models)
|
||||
clone.app_configs = copy.deepcopy(self.app_configs)
|
||||
@@ -358,9 +352,9 @@ class StateApps(Apps):
|
||||
|
||||
class ModelState:
|
||||
"""
|
||||
Represents a Django Model. We don't use the actual Model class
|
||||
as it's not designed to have its options changed - instead, we
|
||||
mutate this one and then render it into a Model as required.
|
||||
Represent a Django Model. Don't use the actual Model class as it's not
|
||||
designed to have its options changed - instead, mutate this one and then
|
||||
render it into a Model as required.
|
||||
|
||||
Note that while you are allowed to mutate .fields, you are not allowed
|
||||
to mutate the Field instances inside there themselves - you must instead
|
||||
@@ -409,9 +403,7 @@ class ModelState:
|
||||
|
||||
@classmethod
|
||||
def from_model(cls, model, exclude_rels=False):
|
||||
"""
|
||||
Feed me a model, get a ModelState representing it out.
|
||||
"""
|
||||
"""Given a model, return a ModelState representing it."""
|
||||
# Deconstruct the fields
|
||||
fields = []
|
||||
for field in model._meta.local_fields:
|
||||
@@ -532,7 +524,7 @@ class ModelState:
|
||||
)
|
||||
|
||||
def construct_managers(self):
|
||||
"Deep-clone the managers using deconstruction"
|
||||
"""Deep-clone the managers using deconstruction."""
|
||||
# Sort all managers by their creation counter
|
||||
sorted_managers = sorted(self.managers, key=lambda v: v[1].creation_counter)
|
||||
for mgr_name, manager in sorted_managers:
|
||||
@@ -546,7 +538,7 @@ class ModelState:
|
||||
yield mgr_name, manager_class(*args, **kwargs)
|
||||
|
||||
def clone(self):
|
||||
"Returns an exact copy of this ModelState"
|
||||
"""Return an exact copy of this ModelState."""
|
||||
return self.__class__(
|
||||
app_label=self.app_label,
|
||||
name=self.name,
|
||||
@@ -557,7 +549,7 @@ class ModelState:
|
||||
)
|
||||
|
||||
def render(self, apps):
|
||||
"Creates a Model object from our current state into the given apps"
|
||||
"""Create a Model object from our current state into the given apps."""
|
||||
# First, make a Meta object
|
||||
meta_contents = {'app_label': self.app_label, "apps": apps}
|
||||
meta_contents.update(self.options)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
def topological_sort_as_sets(dependency_graph):
|
||||
"""Variation of Kahn's algorithm (1962) that returns sets.
|
||||
"""
|
||||
Variation of Kahn's algorithm (1962) that returns sets.
|
||||
|
||||
Takes a dependency graph as a dictionary of node => dependencies.
|
||||
Take a dependency graph as a dictionary of node => dependencies.
|
||||
|
||||
Yields sets of items in topological order, where the first set contains
|
||||
Yield sets of items in topological order, where the first set contains
|
||||
all nodes without dependencies, and each following set contains all
|
||||
nodes that may depend on the nodes only in the previously yielded sets.
|
||||
"""
|
||||
|
||||
@@ -129,7 +129,7 @@ class OperationWriter:
|
||||
|
||||
class MigrationWriter:
|
||||
"""
|
||||
Takes a Migration instance and is able to produce the contents
|
||||
Take a Migration instance and is able to produce the contents
|
||||
of the migration file from it.
|
||||
"""
|
||||
|
||||
@@ -138,9 +138,7 @@ class MigrationWriter:
|
||||
self.needs_manual_porting = False
|
||||
|
||||
def as_string(self):
|
||||
"""
|
||||
Returns a string of the file contents.
|
||||
"""
|
||||
"""Return a string of the file contents."""
|
||||
items = {
|
||||
"replaces_str": "",
|
||||
"initial_str": "",
|
||||
|
||||
Reference in New Issue
Block a user