diff --git a/django/core/management.py b/django/core/management.py index ecb8a4cd5e..0e6db20a13 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -178,6 +178,7 @@ def _get_sql_model_create(model, known_models=set()): rel_field = f data_type = f.get_internal_type() col_type = data_types[data_type] + tablespace = f.tablespace or opts.tablespace if col_type is not None: # Make the definition (e.g. 'foo VARCHAR(30)') for this field. field_output = [style.SQL_FIELD(backend.quote_name(f.column)), @@ -187,6 +188,10 @@ def _get_sql_model_create(model, known_models=set()): field_output.append(style.SQL_KEYWORD('UNIQUE')) if f.primary_key: field_output.append(style.SQL_KEYWORD('PRIMARY KEY')) + if tablespace and backend.supports_tablespaces and (f.unique or f.primary_key) and backend.autoindexes_primary_keys: + # We must specify the index tablespace inline, because we + # won't be generating a CREATE INDEX statement for this field. + field_output.append(backend.get_tablespace_sql(tablespace, inline=True)) if f.rel: if f.rel.to in known_models: field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ @@ -212,7 +217,7 @@ def _get_sql_model_create(model, known_models=set()): full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) full_statement.append(')') if opts.tablespace and backend.supports_tablespaces: - full_statement.append(backend.get_tablespace_sql() % backend.quote_name(opts.tablespace)) + full_statement.append(backend.get_tablespace_sql(opts.tablespace)) full_statement.append(';') final_output.append('\n'.join(full_statement)) @@ -261,12 +266,18 @@ def _get_many_to_many_sql_for_model(model): final_output = [] for f in opts.many_to_many: if not isinstance(f.rel, GenericRel): + tablespace = f.tablespace or opts.tablespace + if tablespace and backend.supports_tablespaces and backend.autoindexes_primary_keys: + tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace, inline=True) + else: + tablespace_sql = '' table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' ('] - table_output.append(' %s %s %s,' % \ + table_output.append(' %s %s %s%s,' % \ (style.SQL_FIELD(backend.quote_name('id')), style.SQL_COLTYPE(data_types['AutoField']), - style.SQL_KEYWORD('NOT NULL PRIMARY KEY'))) + style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), + tablespace_sql)) table_output.append(' %s %s %s %s (%s)%s,' % \ (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__), @@ -281,13 +292,15 @@ def _get_many_to_many_sql_for_model(model): style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)), style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)), backend.get_deferrable_sql())) - table_output.append(' %s (%s, %s)' % \ + table_output.append(' %s (%s, %s)%s' % \ (style.SQL_KEYWORD('UNIQUE'), style.SQL_FIELD(backend.quote_name(f.m2m_column_name())), - style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())))) + style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())), + tablespace_sql)) table_output.append(')') if opts.tablespace and backend.supports_tablespaces: - table_output.append(backend.get_tablespace_sql() % opts.tablespace) + # f.tablespace is only for indices, so ignore its value here. + table_output.append(backend.get_tablespace_sql(opts.tablespace)) table_output.append(';') final_output.append('\n'.join(table_output)) @@ -468,14 +481,20 @@ def get_sql_indexes_for_model(model): output = [] for f in model._meta.fields: - if f.db_index and not (f.primary_key and backend.autoindexes_primary_keys): + if f.db_index and not ((f.primary_key or f.unique) and backend.autoindexes_primary_keys): unique = f.unique and 'UNIQUE ' or '' + tablespace = f.tablespace or model._meta.tablespace + if tablespace and backend.supports_tablespaces: + tablespace_sql = ' ' + backend.get_tablespace_sql(tablespace) + else: + tablespace_sql = '' output.append( style.SQL_KEYWORD('CREATE %sINDEX' % unique) + ' ' + \ style.SQL_TABLE(backend.quote_name('%s_%s' % (model._meta.db_table, f.column))) + ' ' + \ style.SQL_KEYWORD('ON') + ' ' + \ style.SQL_TABLE(backend.quote_name(model._meta.db_table)) + ' ' + \ - "(%s);" % style.SQL_FIELD(backend.quote_name(f.column)) + "(%s)" % style.SQL_FIELD(backend.quote_name(f.column)) + \ + "%s;" % tablespace_sql ) return output diff --git a/django/db/backends/ado_mssql/base.py b/django/db/backends/ado_mssql/base.py index 8cc01862fd..81c947206e 100644 --- a/django/db/backends/ado_mssql/base.py +++ b/django/db/backends/ado_mssql/base.py @@ -154,8 +154,8 @@ def get_max_name_length(): def get_start_transaction_sql(): return "BEGIN;" -def get_tablespace_sql(): - return "ON %s" +def get_tablespace_sql(tablespace, inline=False): + return "ON %s" % quote_name(tablespace) def get_autoinc_sql(table): return None diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 16aab54446..36076de016 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -137,7 +137,7 @@ autoindexes_primary_keys = False needs_datetime_string_cast = True # MySQLdb requires a typecast for dates needs_upper_for_iops = False supports_constraints = True -supports_tablespaces = True +supports_tablespaces = False uses_case_insensitive_names = False def quote_name(name): @@ -201,9 +201,6 @@ def get_max_name_length(): def get_start_transaction_sql(): return "BEGIN;" -def get_tablespace_sql(): - return "TABLESPACE %s STORAGE DISK" - def get_autoinc_sql(table): return None diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 46282c3003..42cf051a34 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -169,8 +169,8 @@ def get_max_name_length(): def get_start_transaction_sql(): return None -def get_tablespace_sql(): - return "TABLESPACE %s" +def get_tablespace_sql(tablespace, inline=False): + return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), quote_name(tablespace)) def get_autoinc_sql(table): # To simulate auto-incrementing primary keys in Oracle, we have to diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index 3abd6d3a49..f490427002 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -110,7 +110,7 @@ autoindexes_primary_keys = True needs_datetime_string_cast = True needs_upper_for_iops = False supports_constraints = True -supports_tablespaces = True +supports_tablespaces = False uses_case_insensitive_names = False def quote_name(name): @@ -174,9 +174,6 @@ def get_max_name_length(): def get_start_transaction_sql(): return "BEGIN;" -def get_tablespace_sql(): - return "TABLESPACE %s" - def get_autoinc_sql(table): return None diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index 9e846304ce..7cc954c920 100644 --- a/django/db/backends/postgresql_psycopg2/base.py +++ b/django/db/backends/postgresql_psycopg2/base.py @@ -78,7 +78,7 @@ autoindexes_primary_keys = True needs_datetime_string_cast = False needs_upper_for_iops = False supports_constraints = True -supports_tablespaces = True +supports_tablespaces = False uses_case_insensitive_names = True def quote_name(name): @@ -134,9 +134,6 @@ def get_max_name_length(): def get_start_transaction_sql(): return "BEGIN;" -def get_tablespace_sql(): - return "TABLESPACE %s" - def get_autoinc_sql(table): return None diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index d7cc279608..bf3f535a84 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -70,7 +70,7 @@ class Field(object): core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True, prepopulate_from=None, unique_for_date=None, unique_for_month=None, unique_for_year=None, validator_list=None, choices=None, radio_admin=None, - help_text='', db_column=None): + help_text='', db_column=None, tablespace=None): self.name = name self.verbose_name = verbose_name self.primary_key = primary_key @@ -87,6 +87,7 @@ class Field(object): self.radio_admin = radio_admin self.help_text = help_text self.db_column = db_column + self.tablespace = tablespace # Set db_index to True if the field has a relationship and doesn't explicitly set db_index. self.db_index = db_index