Commit d0ecefc2 authored by Andrew Godwin's avatar Andrew Godwin
Browse files

Start adding operations that work and tests for them

parent 264f8650
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -272,7 +272,7 @@ class BaseDatabaseSchemaEditor(object):
            "new_tablespace": self.quote_name(new_db_tablespace),
        })

    def create_field(self, model, field, keep_default=False):
    def add_field(self, model, field, keep_default=False):
        """
        Creates a field on a model.
        Usually involves adding a column, but may involve adding a
@@ -325,7 +325,7 @@ class BaseDatabaseSchemaEditor(object):
                }
            )

    def delete_field(self, model, field):
    def remove_field(self, model, field):
        """
        Removes a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
+2 −2
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
        if restore_pk_field:
            restore_pk_field.primary_key = True

    def create_field(self, model, field):
    def add_field(self, model, field):
        """
        Creates a field on a model.
        Usually involves adding a column, but may involve adding a
@@ -89,7 +89,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
            raise ValueError("You cannot add a null=False column without a default value on SQLite.")
        self._remake_table(model, create_fields=[field])

    def delete_field(self, model, field):
    def remove_field(self, model, field):
        """
        Removes a field from a model. Usually involves deleting a column,
        but for M2Ms may involve deleting a table.
+1 −0
Original line number Diff line number Diff line
from .migration import Migration
from .operations import *
+15 −2
Original line number Diff line number Diff line
from django.utils.datastructures import SortedSet
from django.db.migrations.state import ProjectState


class MigrationGraph(object):
@@ -33,8 +34,10 @@ class MigrationGraph(object):
        self.nodes[node] = implementation

    def add_dependency(self, child, parent):
        self.nodes[child] = None
        self.nodes[parent] = None
        if child not in self.nodes:
            raise KeyError("Dependency references nonexistent child node %r" % (child,))
        if parent not in self.nodes:
            raise KeyError("Dependency references nonexistent parent node %r" % (parent,))
        self.dependencies.setdefault(child, set()).add(parent)
        self.dependents.setdefault(parent, set()).add(child)

@@ -117,6 +120,16 @@ class MigrationGraph(object):
    def __str__(self):
        return "Graph: %s nodes, %s edges" % (len(self.nodes), sum(len(x) for x in self.dependencies.values()))

    def project_state(self, node):
        """
        Given a migration node, returns a complete ProjectState for it.
        """
        plan = self.forwards_plan(node)
        project_state = ProjectState()
        for node in plan:
            project_state = self.nodes[node].mutate_state(project_state)
        return project_state


class CircularDependencyError(Exception):
    """
+5 −2
Original line number Diff line number Diff line
import os
from django.utils.importlib import import_module
from django.utils.functional import cached_property
from django.db.models.loading import cache
from django.db.migrations.recorder import MigrationRecorder
from django.db.migrations.graph import MigrationGraph
@@ -64,9 +65,10 @@ class MigrationLoader(object):
                migration_module = import_module("%s.%s" % (module_name, migration_name))
                if not hasattr(migration_module, "Migration"):
                    raise BadMigrationError("Migration %s in app %s has no Migration class" % (migration_name, app_label))
                self.disk_migrations[app_label, migration_name] = migration_module.Migration
                self.disk_migrations[app_label, migration_name] = migration_module.Migration(migration_name, app_label)

    def build_graph(self):
    @cached_property
    def graph(self):
        """
        Builds a migration dependency graph using both the disk and database.
        """
@@ -116,6 +118,7 @@ class MigrationLoader(object):
        graph = MigrationGraph()
        for key, migration in normal.items():
            graph.add_node(key, migration)
        for key, migration in normal.items():
            for parent in migration.dependencies:
                graph.add_dependency(key, parent)
        return graph
Loading