Author: mtredinnick
Date: 2007-11-04 00:05:24 -0500 (Sun, 04 Nov 2007)
New Revision: 6650
Modified:
django/trunk/django/core/management/sql.py
django/trunk/django/db/backends/__init__.py
django/trunk/django/db/backends/mysql/base.py
django/trunk/django/db/backends/mysql_old/base.py
Log:
Fixed #5729 -- For MySQL (only), always delay the creation of foreign key
references, for all tables, until after the table has been created. This means
that when using the InnoDB storage engine, true foreign key constraints are
created (inline "REFERENCES" are ignored by InnoDB, unfortunately).
Fully backwards compatible.
Modified: django/trunk/django/core/management/sql.py
===================================================================
--- django/trunk/django/core/management/sql.py 2007-11-04 03:37:04 UTC (rev
6649)
+++ django/trunk/django/core/management/sql.py 2007-11-04 05:05:24 UTC (rev
6650)
@@ -252,6 +252,7 @@
table_output = []
pending_references = {}
qn = connection.ops.quote_name
+ inline_references = connection.features.inline_fk_references
for f in opts.fields:
col_type = f.db_type()
tablespace = f.db_tablespace or opts.db_tablespace
@@ -272,7 +273,7 @@
# won't be generating a CREATE INDEX statement for this field.
field_output.append(connection.ops.tablespace_sql(tablespace,
inline=True))
if f.rel:
- if f.rel.to in known_models:
+ if inline_references and f.rel.to in known_models:
field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
style.SQL_TABLE(qn(f.rel.to._meta.db_table)) + ' (' + \
style.SQL_FIELD(qn(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')' +
@@ -341,10 +342,12 @@
def many_to_many_sql_for_model(model, style):
from django.db import connection, models
from django.contrib.contenttypes import generic
+ from django.db.backends.util import truncate_name
opts = model._meta
final_output = []
qn = connection.ops.quote_name
+ inline_references = connection.features.inline_fk_references
for f in opts.many_to_many:
if not isinstance(f.rel, generic.GenericRel):
tablespace = f.db_tablespace or opts.db_tablespace
@@ -354,26 +357,43 @@
tablespace_sql = ''
table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
style.SQL_TABLE(qn(f.m2m_db_table())) + ' (']
- table_output.append(' %s %s %s%s,' % \
+ table_output.append(' %s %s %s%s,' %
(style.SQL_FIELD(qn('id')),
style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()),
style.SQL_KEYWORD('NOT NULL PRIMARY KEY'),
tablespace_sql))
- table_output.append(' %s %s %s %s (%s)%s,' % \
- (style.SQL_FIELD(qn(f.m2m_column_name())),
- style.SQL_COLTYPE(models.ForeignKey(model).db_type()),
- style.SQL_KEYWORD('NOT NULL REFERENCES'),
- style.SQL_TABLE(qn(opts.db_table)),
- style.SQL_FIELD(qn(opts.pk.column)),
- connection.ops.deferrable_sql()))
- table_output.append(' %s %s %s %s (%s)%s,' % \
- (style.SQL_FIELD(qn(f.m2m_reverse_name())),
- style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()),
- style.SQL_KEYWORD('NOT NULL REFERENCES'),
- style.SQL_TABLE(qn(f.rel.to._meta.db_table)),
- style.SQL_FIELD(qn(f.rel.to._meta.pk.column)),
- connection.ops.deferrable_sql()))
- table_output.append(' %s (%s, %s)%s' % \
+ if inline_references:
+ deferred = []
+ table_output.append(' %s %s %s %s (%s)%s,' %
+ (style.SQL_FIELD(qn(f.m2m_column_name())),
+ style.SQL_COLTYPE(models.ForeignKey(model).db_type()),
+ style.SQL_KEYWORD('NOT NULL REFERENCES'),
+ style.SQL_TABLE(qn(opts.db_table)),
+ style.SQL_FIELD(qn(opts.pk.column)),
+ connection.ops.deferrable_sql()))
+ table_output.append(' %s %s %s %s (%s)%s,' %
+ (style.SQL_FIELD(qn(f.m2m_reverse_name())),
+ style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()),
+ style.SQL_KEYWORD('NOT NULL REFERENCES'),
+ style.SQL_TABLE(qn(f.rel.to._meta.db_table)),
+ style.SQL_FIELD(qn(f.rel.to._meta.pk.column)),
+ connection.ops.deferrable_sql()))
+ else:
+ table_output.append(' %s %s %s,' %
+ (style.SQL_FIELD(qn(f.m2m_column_name())),
+ style.SQL_COLTYPE(models.ForeignKey(model).db_type()),
+ style.SQL_KEYWORD('NOT NULL')))
+ table_output.append(' %s %s %s,' %
+ (style.SQL_FIELD(qn(f.m2m_reverse_name())),
+ style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()),
+ style.SQL_KEYWORD('NOT NULL')))
+ deferred = [
+ (f.m2m_db_table(), f.m2m_column_name(), opts.db_table,
+ opts.pk.column),
+ ( f.m2m_db_table(), f.m2m_reverse_name(),
+ f.rel.to._meta.db_table, f.rel.to._meta.pk.column)
+ ]
+ table_output.append(' %s (%s, %s)%s' %
(style.SQL_KEYWORD('UNIQUE'),
style.SQL_FIELD(qn(f.m2m_column_name())),
style.SQL_FIELD(qn(f.m2m_reverse_name())),
@@ -385,6 +405,15 @@
table_output.append(';')
final_output.append('\n'.join(table_output))
+ for r_table, r_col, table, col in deferred:
+ r_name = '%s_refs_%s_%x' % (r_col, col,
+ abs(hash((r_table, table))))
+ final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s
ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' %
+ (qn(r_table),
+ truncate_name(r_name, connection.ops.max_name_length()),
+ qn(r_col), qn(table), qn(col),
+ connection.ops.deferrable_sql()))
+
# Add any extra SQL needed to support auto-incrementing PKs
autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table(), 'id')
if autoinc_sql:
Modified: django/trunk/django/db/backends/__init__.py
===================================================================
--- django/trunk/django/db/backends/__init__.py 2007-11-04 03:37:04 UTC (rev
6649)
+++ django/trunk/django/db/backends/__init__.py 2007-11-04 05:05:24 UTC (rev
6650)
@@ -43,6 +43,7 @@
allows_group_by_ordinal = True
allows_unique_and_pk = True
autoindexes_primary_keys = True
+ inline_fk_references = True
needs_datetime_string_cast = True
needs_upper_for_iops = False
supports_constraints = True
Modified: django/trunk/django/db/backends/mysql/base.py
===================================================================
--- django/trunk/django/db/backends/mysql/base.py 2007-11-04 03:37:04 UTC
(rev 6649)
+++ django/trunk/django/db/backends/mysql/base.py 2007-11-04 05:05:24 UTC
(rev 6650)
@@ -61,6 +61,7 @@
class DatabaseFeatures(BaseDatabaseFeatures):
autoindexes_primary_keys = False
+ inline_fk_references = False
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):
Modified: django/trunk/django/db/backends/mysql_old/base.py
===================================================================
--- django/trunk/django/db/backends/mysql_old/base.py 2007-11-04 03:37:04 UTC
(rev 6649)
+++ django/trunk/django/db/backends/mysql_old/base.py 2007-11-04 05:05:24 UTC
(rev 6650)
@@ -65,6 +65,7 @@
class DatabaseFeatures(BaseDatabaseFeatures):
autoindexes_primary_keys = False
+ inline_fk_references = False
class DatabaseOperations(BaseDatabaseOperations):
def date_extract_sql(self, lookup_type, field_name):
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---