Refs #26889 -- Refactored SchemaEditor to allow backend specific indexes.

This commit is contained in:
Jon Dufresne 2016-07-15 07:34:37 -07:00 committed by Tim Graham
parent f8bfa80680
commit 3f76d1402d
3 changed files with 15 additions and 18 deletions

View File

@ -430,8 +430,7 @@ class BaseDatabaseSchemaEditor(object):
} }
self.execute(sql) self.execute(sql)
# Add an index, if required # Add an index, if required
if field.db_index and not field.unique: self.deferred_sql.extend(self._field_indexes_sql(model, field))
self.deferred_sql.append(self._create_index_sql(model, [field]))
# Add any FK constraints later # Add any FK constraints later
if field.remote_field and self.connection.features.supports_foreign_keys and field.db_constraint: if field.remote_field and self.connection.features.supports_foreign_keys and field.db_constraint:
self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s")) self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
@ -897,14 +896,22 @@ class BaseDatabaseSchemaEditor(object):
return [] return []
output = [] output = []
for field in model._meta.local_fields: for field in model._meta.local_fields:
if self._field_should_be_indexed(model, field): output.extend(self._field_indexes_sql(model, field))
output.append(self._create_index_sql(model, [field], suffix=""))
for field_names in model._meta.index_together: for field_names in model._meta.index_together:
fields = [model._meta.get_field(field) for field in field_names] fields = [model._meta.get_field(field) for field in field_names]
output.append(self._create_index_sql(model, fields, suffix="_idx")) output.append(self._create_index_sql(model, fields, suffix="_idx"))
return output return output
def _field_indexes_sql(self, model, field):
"""
Return a list of all index SQL statements for the specified field.
"""
output = []
if self._field_should_be_indexed(model, field):
output.append(self._create_index_sql(model, [field]))
return output
def _field_should_be_indexed(self, model, field): def _field_should_be_indexed(self, model, field):
return field.db_index and not field.unique return field.db_index and not field.unique

View File

@ -17,18 +17,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
def quote_value(self, value): def quote_value(self, value):
return psycopg2.extensions.adapt(value) return psycopg2.extensions.adapt(value)
def add_field(self, model, field): def _field_indexes_sql(self, model, field):
super(DatabaseSchemaEditor, self).add_field(model, field) output = super(DatabaseSchemaEditor, self)._field_indexes_sql(model, field)
like_index_statement = self._create_like_index_sql(model, field)
if like_index_statement is not None:
self.deferred_sql.append(like_index_statement)
def _model_indexes_sql(self, model):
output = super(DatabaseSchemaEditor, self)._model_indexes_sql(model)
if not model._meta.managed or model._meta.proxy or model._meta.swapped:
return output
for field in model._meta.local_fields:
like_index_statement = self._create_like_index_sql(model, field) like_index_statement = self._create_like_index_sql(model, field)
if like_index_statement is not None: if like_index_statement is not None:
output.append(like_index_statement) output.append(like_index_statement)

View File

@ -46,7 +46,7 @@ class SchemaIndexesTests(TestCase):
from .models import IndexedArticle from .models import IndexedArticle
index_sql = connection.schema_editor()._model_indexes_sql(IndexedArticle) index_sql = connection.schema_editor()._model_indexes_sql(IndexedArticle)
self.assertEqual(len(index_sql), 5) self.assertEqual(len(index_sql), 5)
self.assertIn('("headline" varchar_pattern_ops)', index_sql[2]) self.assertIn('("headline" varchar_pattern_ops)', index_sql[1])
self.assertIn('("body" text_pattern_ops)', index_sql[3]) self.assertIn('("body" text_pattern_ops)', index_sql[3])
# unique=True and db_index=True should only create the varchar-specific # unique=True and db_index=True should only create the varchar-specific
# index (#19441). # index (#19441).