From f9df4d1435fd3382fdcc06f75c1c8d62bfe78ec6 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Mon, 30 Jun 2008 04:46:59 +0000 Subject: [PATCH] Make sure we only create the minimum number of table indexes for MySQL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch simplifies a bunch of code for all backends and removes some duplicate index creation for MySQL, in particular (versions 4.x and later). Patch from Nis Jørgensen. Fixed #5671, #5680, #7170, #7186. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7790 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/core/management/commands/createcachetable.py | 4 ++-- django/core/management/sql.py | 13 ++++++------- django/db/backends/__init__.py | 2 -- django/db/backends/mysql/base.py | 1 - django/db/backends/mysql_old/base.py | 1 - django/db/backends/oracle/base.py | 1 - django/db/models/fields/__init__.py | 6 +++++- 8 files changed, 14 insertions(+), 15 deletions(-) diff --git a/AUTHORS b/AUTHORS index 94dc8891a4..ad3c88354c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -192,6 +192,7 @@ answer newbie questions, and generally made Django that much better: james_027@yahoo.com jcrasta@gmail.com Zak Johnson + Nis Jørgensen Michael Josephson jpellerin@gmail.com junzhang.jn@gmail.com diff --git a/django/core/management/commands/createcachetable.py b/django/core/management/commands/createcachetable.py index c8df8d04f7..098bca793f 100644 --- a/django/core/management/commands/createcachetable.py +++ b/django/core/management/commands/createcachetable.py @@ -21,10 +21,10 @@ class Command(LabelCommand): for f in fields: field_output = [qn(f.name), f.db_type()] field_output.append("%sNULL" % (not f.null and "NOT " or "")) - if f.unique: - field_output.append("UNIQUE") if f.primary_key: field_output.append("PRIMARY KEY") + elif f.unique: + field_output.append("UNIQUE") if f.db_index: unique = f.unique and "UNIQUE " or "" index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \ diff --git a/django/core/management/sql.py b/django/core/management/sql.py index c635fcab8a..000886ada5 100644 --- a/django/core/management/sql.py +++ b/django/core/management/sql.py @@ -268,11 +268,11 @@ def sql_model_create(model, style, known_models=set()): field_output = [style.SQL_FIELD(qn(f.column)), style.SQL_COLTYPE(col_type)] field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or ''))) - if f.unique and (not f.primary_key or connection.features.allows_unique_and_pk): - field_output.append(style.SQL_KEYWORD('UNIQUE')) if f.primary_key: field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) - if tablespace and connection.features.supports_tablespaces and (f.unique or f.primary_key) and connection.features.autoindexes_primary_keys: + elif f.unique: + field_output.append(style.SQL_KEYWORD('UNIQUE')) + if tablespace and connection.features.supports_tablespaces and f.unique: # We must specify the index tablespace inline, because we # won't be generating a CREATE INDEX statement for this field. field_output.append(connection.ops.tablespace_sql(tablespace, inline=True)) @@ -355,7 +355,7 @@ def many_to_many_sql_for_model(model, style): for f in opts.local_many_to_many: if not isinstance(f.rel, generic.GenericRel): tablespace = f.db_tablespace or opts.db_tablespace - if tablespace and connection.features.supports_tablespaces and connection.features.autoindexes_primary_keys: + if tablespace and connection.features.supports_tablespaces: tablespace_sql = ' ' + connection.ops.tablespace_sql(tablespace, inline=True) else: tablespace_sql = '' @@ -460,15 +460,14 @@ def sql_indexes_for_model(model, style): qn = connection.ops.quote_name for f in model._meta.local_fields: - if f.db_index and not ((f.primary_key or f.unique) and connection.features.autoindexes_primary_keys): - unique = f.unique and 'UNIQUE ' or '' + if f.db_index and not f.unique: tablespace = f.db_tablespace or model._meta.db_tablespace if tablespace and connection.features.supports_tablespaces: tablespace_sql = ' ' + connection.ops.tablespace_sql(tablespace) else: tablespace_sql = '' output.append( - style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ + style.SQL_KEYWORD('CREATE INDEX') + ' ' + \ style.SQL_TABLE(qn('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ style.SQL_KEYWORD('ON') + ' ' + \ style.SQL_TABLE(qn(model._meta.db_table)) + ' ' + \ diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index 7a4e46a7d7..36a2339638 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -41,8 +41,6 @@ class BaseDatabaseWrapper(local): class BaseDatabaseFeatures(object): allows_group_by_ordinal = True - allows_unique_and_pk = True - autoindexes_primary_keys = True inline_fk_references = True needs_datetime_string_cast = True supports_constraints = True diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 23735a023b..cfa6b0e56c 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -60,7 +60,6 @@ server_version_re = re.compile(r'(\d{1,2})\.(\d{1,2})\.(\d{1,2})') # TRADITIONAL will automatically cause most warnings to be treated as errors. class DatabaseFeatures(BaseDatabaseFeatures): - autoindexes_primary_keys = False inline_fk_references = False empty_fetchmany_value = () update_can_self_select = False diff --git a/django/db/backends/mysql_old/base.py b/django/db/backends/mysql_old/base.py index e57aee6a04..adfa03d569 100644 --- a/django/db/backends/mysql_old/base.py +++ b/django/db/backends/mysql_old/base.py @@ -64,7 +64,6 @@ class MysqlDebugWrapper: return getattr(self.cursor, attr) class DatabaseFeatures(BaseDatabaseFeatures): - autoindexes_primary_keys = False inline_fk_references = False empty_fetchmany_value = () update_can_self_select = False diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 1df6bac069..54517662c1 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -24,7 +24,6 @@ IntegrityError = Database.IntegrityError class DatabaseFeatures(BaseDatabaseFeatures): allows_group_by_ordinal = False - allows_unique_and_pk = False # Suppress UNIQUE/PK for Oracle (ORA-02259) empty_fetchmany_value = () needs_datetime_string_cast = False supports_tablespaces = True diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index a893c25e63..dc5cb9609c 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -91,7 +91,7 @@ class Field(object): self.name = name self.verbose_name = verbose_name self.primary_key = primary_key - self.max_length, self.unique = max_length, unique + self.max_length, self._unique = max_length, unique self.blank, self.null = blank, null # Oracle treats the empty string ('') as null, so coerce the null # option whenever '' is a possible value. @@ -168,6 +168,10 @@ class Field(object): except KeyError: return None + def unique(self): + return self._unique or self.primary_key + unique = property(unique) + def validate_full(self, field_data, all_data): """ Returns a list of errors for this field. This is the main interface,