Make sure we only create the minimum number of table indexes for MySQL.
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
This commit is contained in:
parent
b0bc8b9dfd
commit
f9df4d1435
1
AUTHORS
1
AUTHORS
|
@ -192,6 +192,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
james_027@yahoo.com
|
james_027@yahoo.com
|
||||||
jcrasta@gmail.com
|
jcrasta@gmail.com
|
||||||
Zak Johnson <zakj@nox.cx>
|
Zak Johnson <zakj@nox.cx>
|
||||||
|
Nis Jørgensen <nis@superlativ.dk>
|
||||||
Michael Josephson <http://www.sdjournal.com/>
|
Michael Josephson <http://www.sdjournal.com/>
|
||||||
jpellerin@gmail.com
|
jpellerin@gmail.com
|
||||||
junzhang.jn@gmail.com
|
junzhang.jn@gmail.com
|
||||||
|
|
|
@ -21,10 +21,10 @@ class Command(LabelCommand):
|
||||||
for f in fields:
|
for f in fields:
|
||||||
field_output = [qn(f.name), f.db_type()]
|
field_output = [qn(f.name), f.db_type()]
|
||||||
field_output.append("%sNULL" % (not f.null and "NOT " or ""))
|
field_output.append("%sNULL" % (not f.null and "NOT " or ""))
|
||||||
if f.unique:
|
|
||||||
field_output.append("UNIQUE")
|
|
||||||
if f.primary_key:
|
if f.primary_key:
|
||||||
field_output.append("PRIMARY KEY")
|
field_output.append("PRIMARY KEY")
|
||||||
|
elif f.unique:
|
||||||
|
field_output.append("UNIQUE")
|
||||||
if f.db_index:
|
if f.db_index:
|
||||||
unique = f.unique and "UNIQUE " or ""
|
unique = f.unique and "UNIQUE " or ""
|
||||||
index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \
|
index_output.append("CREATE %sINDEX %s_%s ON %s (%s);" % \
|
||||||
|
|
|
@ -268,11 +268,11 @@ def sql_model_create(model, style, known_models=set()):
|
||||||
field_output = [style.SQL_FIELD(qn(f.column)),
|
field_output = [style.SQL_FIELD(qn(f.column)),
|
||||||
style.SQL_COLTYPE(col_type)]
|
style.SQL_COLTYPE(col_type)]
|
||||||
field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')))
|
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:
|
if f.primary_key:
|
||||||
field_output.append(style.SQL_KEYWORD('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
|
# We must specify the index tablespace inline, because we
|
||||||
# won't be generating a CREATE INDEX statement for this field.
|
# won't be generating a CREATE INDEX statement for this field.
|
||||||
field_output.append(connection.ops.tablespace_sql(tablespace, inline=True))
|
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:
|
for f in opts.local_many_to_many:
|
||||||
if not isinstance(f.rel, generic.GenericRel):
|
if not isinstance(f.rel, generic.GenericRel):
|
||||||
tablespace = f.db_tablespace or opts.db_tablespace
|
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)
|
tablespace_sql = ' ' + connection.ops.tablespace_sql(tablespace, inline=True)
|
||||||
else:
|
else:
|
||||||
tablespace_sql = ''
|
tablespace_sql = ''
|
||||||
|
@ -460,15 +460,14 @@ def sql_indexes_for_model(model, style):
|
||||||
|
|
||||||
qn = connection.ops.quote_name
|
qn = connection.ops.quote_name
|
||||||
for f in model._meta.local_fields:
|
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):
|
if f.db_index and not f.unique:
|
||||||
unique = f.unique and 'UNIQUE ' or ''
|
|
||||||
tablespace = f.db_tablespace or model._meta.db_tablespace
|
tablespace = f.db_tablespace or model._meta.db_tablespace
|
||||||
if tablespace and connection.features.supports_tablespaces:
|
if tablespace and connection.features.supports_tablespaces:
|
||||||
tablespace_sql = ' ' + connection.ops.tablespace_sql(tablespace)
|
tablespace_sql = ' ' + connection.ops.tablespace_sql(tablespace)
|
||||||
else:
|
else:
|
||||||
tablespace_sql = ''
|
tablespace_sql = ''
|
||||||
output.append(
|
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_TABLE(qn('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \
|
||||||
style.SQL_KEYWORD('ON') + ' ' + \
|
style.SQL_KEYWORD('ON') + ' ' + \
|
||||||
style.SQL_TABLE(qn(model._meta.db_table)) + ' ' + \
|
style.SQL_TABLE(qn(model._meta.db_table)) + ' ' + \
|
||||||
|
|
|
@ -41,8 +41,6 @@ class BaseDatabaseWrapper(local):
|
||||||
|
|
||||||
class BaseDatabaseFeatures(object):
|
class BaseDatabaseFeatures(object):
|
||||||
allows_group_by_ordinal = True
|
allows_group_by_ordinal = True
|
||||||
allows_unique_and_pk = True
|
|
||||||
autoindexes_primary_keys = True
|
|
||||||
inline_fk_references = True
|
inline_fk_references = True
|
||||||
needs_datetime_string_cast = True
|
needs_datetime_string_cast = True
|
||||||
supports_constraints = True
|
supports_constraints = True
|
||||||
|
|
|
@ -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.
|
# TRADITIONAL will automatically cause most warnings to be treated as errors.
|
||||||
|
|
||||||
class DatabaseFeatures(BaseDatabaseFeatures):
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
autoindexes_primary_keys = False
|
|
||||||
inline_fk_references = False
|
inline_fk_references = False
|
||||||
empty_fetchmany_value = ()
|
empty_fetchmany_value = ()
|
||||||
update_can_self_select = False
|
update_can_self_select = False
|
||||||
|
|
|
@ -64,7 +64,6 @@ class MysqlDebugWrapper:
|
||||||
return getattr(self.cursor, attr)
|
return getattr(self.cursor, attr)
|
||||||
|
|
||||||
class DatabaseFeatures(BaseDatabaseFeatures):
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
autoindexes_primary_keys = False
|
|
||||||
inline_fk_references = False
|
inline_fk_references = False
|
||||||
empty_fetchmany_value = ()
|
empty_fetchmany_value = ()
|
||||||
update_can_self_select = False
|
update_can_self_select = False
|
||||||
|
|
|
@ -24,7 +24,6 @@ IntegrityError = Database.IntegrityError
|
||||||
|
|
||||||
class DatabaseFeatures(BaseDatabaseFeatures):
|
class DatabaseFeatures(BaseDatabaseFeatures):
|
||||||
allows_group_by_ordinal = False
|
allows_group_by_ordinal = False
|
||||||
allows_unique_and_pk = False # Suppress UNIQUE/PK for Oracle (ORA-02259)
|
|
||||||
empty_fetchmany_value = ()
|
empty_fetchmany_value = ()
|
||||||
needs_datetime_string_cast = False
|
needs_datetime_string_cast = False
|
||||||
supports_tablespaces = True
|
supports_tablespaces = True
|
||||||
|
|
|
@ -91,7 +91,7 @@ class Field(object):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.verbose_name = verbose_name
|
self.verbose_name = verbose_name
|
||||||
self.primary_key = primary_key
|
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
|
self.blank, self.null = blank, null
|
||||||
# Oracle treats the empty string ('') as null, so coerce the null
|
# Oracle treats the empty string ('') as null, so coerce the null
|
||||||
# option whenever '' is a possible value.
|
# option whenever '' is a possible value.
|
||||||
|
@ -168,6 +168,10 @@ class Field(object):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def unique(self):
|
||||||
|
return self._unique or self.primary_key
|
||||||
|
unique = property(unique)
|
||||||
|
|
||||||
def validate_full(self, field_data, all_data):
|
def validate_full(self, field_data, all_data):
|
||||||
"""
|
"""
|
||||||
Returns a list of errors for this field. This is the main interface,
|
Returns a list of errors for this field. This is the main interface,
|
||||||
|
|
Loading…
Reference in New Issue