1
0
mirror of https://github.com/django/django.git synced 2025-10-29 00:26:07 +00:00

Improve migration optimizer to be able to optimize through other ops

This commit is contained in:
Andrew Godwin
2013-10-16 11:09:33 +01:00
parent 694d7da6c5
commit 42f8666f6a
4 changed files with 124 additions and 5 deletions

View File

@@ -64,6 +64,18 @@ class Operation(object):
"""
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
model name (as a string), with an optional app label for accuracy.
Used for optimization. If in doubt, return True;
returning a false positive will merely make the optimizer a little
less efficient, while returning a false negative may result in an
unusable optimized migration.
"""
return True
def __repr__(self):
return "<%s %s%s>" % (
self.__class__.__name__,

View File

@@ -1,4 +1,5 @@
from .base import Operation
from django.utils import six
from django.db import models, router
from django.db.models.options import normalize_unique_together
from django.db.migrations.state import ModelState
@@ -33,6 +34,23 @@ class CreateModel(Operation):
def describe(self):
return "Create model %s" % (self.name, )
def references_model(self, name, app_label=None):
strings_to_check = [self.name]
# Check we didn't inherit from the model
for base in self.bases:
if isinstance(base, six.string_types):
strings_to_check.append(base.split(".")[-1])
# Check we have no FKs/M2Ms with it
for fname, field in self.fields:
if field.rel:
if isinstance(field.rel.to, six.string_types):
strings_to_check.append(field.rel.to.split(".")[-1])
# Now go over all the strings and compare them
for string in strings_to_check:
if string.lower() == name.lower():
return True
return False
def __eq__(self, other):
return (
(self.__class__ == other.__class__) and
@@ -66,6 +84,9 @@ class DeleteModel(Operation):
if router.allow_migrate(schema_editor.connection.alias, model):
schema_editor.create_model(model)
def references_model(self, name, app_label=None):
return name.lower() == self.name.lower()
def describe(self):
return "Delete model %s" % (self.name, )
@@ -97,6 +118,9 @@ class AlterModelTable(Operation):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
return self.database_forwards(app_label, schema_editor, from_state, to_state)
def references_model(self, name, app_label=None):
return name.lower() == self.name.lower()
def describe(self):
return "Rename table for %s to %s" % (self.name, self.table)
@@ -131,6 +155,9 @@ class AlterUniqueTogether(Operation):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
return self.database_forwards(app_label, schema_editor, from_state, to_state)
def references_model(self, name, app_label=None):
return name.lower() == self.name.lower()
def describe(self):
return "Alter unique_together for %s (%s constraints)" % (self.name, len(self.unique_together))
@@ -164,5 +191,8 @@ class AlterIndexTogether(Operation):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
return self.database_forwards(app_label, schema_editor, from_state, to_state)
def references_model(self, name, app_label=None):
return name.lower() == self.name.lower()
def describe(self):
return "Alter index_together for %s (%s constraints)" % (self.name, len(self.index_together))