Fixed #30444 -- Moved SQL generation for tables to BaseDatabaseSchemaEditor.table_sql().
This commit is contained in:
parent
0e2ed4fdd1
commit
4043dc69cd
1
AUTHORS
1
AUTHORS
|
@ -740,6 +740,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Roberto Aguilar <roberto@baremetal.io>
|
||||
Robert Rock Howard <http://djangomojo.com/>
|
||||
Robert Wittams
|
||||
Rob Golding-Day <rob@golding-day.com>
|
||||
Rob Hudson <https://rob.cogit8.org/>
|
||||
Robin Munn <http://www.geekforgod.com/>
|
||||
Rodrigo Pinheiro Marques de Araújo <fenrrir@gmail.com>
|
||||
|
|
|
@ -140,6 +140,63 @@ class BaseDatabaseSchemaEditor:
|
|||
def quote_name(self, name):
|
||||
return self.connection.ops.quote_name(name)
|
||||
|
||||
def table_sql(self, model):
|
||||
"""Take a model and return its table definition."""
|
||||
# Add any unique_togethers (always deferred, as some fields might be
|
||||
# created afterwards, like geometry fields with some backends).
|
||||
for fields in model._meta.unique_together:
|
||||
columns = [model._meta.get_field(field).column for field in fields]
|
||||
self.deferred_sql.append(self._create_unique_sql(model, columns))
|
||||
# Create column SQL, add FK deferreds if needed.
|
||||
column_sqls = []
|
||||
params = []
|
||||
for field in model._meta.local_fields:
|
||||
# SQL.
|
||||
definition, extra_params = self.column_sql(model, field)
|
||||
if definition is None:
|
||||
continue
|
||||
# Check constraints can go on the column SQL here.
|
||||
db_params = field.db_parameters(connection=self.connection)
|
||||
if db_params['check']:
|
||||
definition += ' ' + self.sql_check_constraint % db_params
|
||||
# Autoincrement SQL (for backends with inline variant).
|
||||
col_type_suffix = field.db_type_suffix(connection=self.connection)
|
||||
if col_type_suffix:
|
||||
definition += ' %s' % col_type_suffix
|
||||
params.extend(extra_params)
|
||||
# FK.
|
||||
if field.remote_field and field.db_constraint:
|
||||
to_table = field.remote_field.model._meta.db_table
|
||||
to_column = field.remote_field.model._meta.get_field(field.remote_field.field_name).column
|
||||
if self.sql_create_inline_fk:
|
||||
definition += ' ' + self.sql_create_inline_fk % {
|
||||
'to_table': self.quote_name(to_table),
|
||||
'to_column': self.quote_name(to_column),
|
||||
}
|
||||
elif self.connection.features.supports_foreign_keys:
|
||||
self.deferred_sql.append(self._create_fk_sql(model, field, '_fk_%(to_table)s_%(to_column)s'))
|
||||
# Add the SQL to our big list.
|
||||
column_sqls.append('%s %s' % (
|
||||
self.quote_name(field.column),
|
||||
definition,
|
||||
))
|
||||
# Autoincrement SQL (for backends with post table definition
|
||||
# variant).
|
||||
if field.get_internal_type() in ('AutoField', 'BigAutoField'):
|
||||
autoinc_sql = self.connection.ops.autoinc_sql(model._meta.db_table, field.column)
|
||||
if autoinc_sql:
|
||||
self.deferred_sql.extend(autoinc_sql)
|
||||
constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints]
|
||||
sql = self.sql_create_table % {
|
||||
'table': self.quote_name(model._meta.db_table),
|
||||
'definition': ', '.join(constraint for constraint in (*column_sqls, *constraints) if constraint),
|
||||
}
|
||||
if model._meta.db_tablespace:
|
||||
tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
|
||||
if tablespace_sql:
|
||||
sql += ' ' + tablespace_sql
|
||||
return sql, params
|
||||
|
||||
# Field <-> database mapping functions
|
||||
|
||||
def column_sql(self, model, field, include_default=False):
|
||||
|
@ -250,60 +307,7 @@ class BaseDatabaseSchemaEditor:
|
|||
Create a table and any accompanying indexes or unique constraints for
|
||||
the given `model`.
|
||||
"""
|
||||
# Create column SQL, add FK deferreds if needed
|
||||
column_sqls = []
|
||||
params = []
|
||||
for field in model._meta.local_fields:
|
||||
# SQL
|
||||
definition, extra_params = self.column_sql(model, field)
|
||||
if definition is None:
|
||||
continue
|
||||
# Check constraints can go on the column SQL here
|
||||
db_params = field.db_parameters(connection=self.connection)
|
||||
if db_params['check']:
|
||||
definition += " " + self.sql_check_constraint % db_params
|
||||
# Autoincrement SQL (for backends with inline variant)
|
||||
col_type_suffix = field.db_type_suffix(connection=self.connection)
|
||||
if col_type_suffix:
|
||||
definition += " %s" % col_type_suffix
|
||||
params.extend(extra_params)
|
||||
# FK
|
||||
if field.remote_field and field.db_constraint:
|
||||
to_table = field.remote_field.model._meta.db_table
|
||||
to_column = field.remote_field.model._meta.get_field(field.remote_field.field_name).column
|
||||
if self.sql_create_inline_fk:
|
||||
definition += " " + self.sql_create_inline_fk % {
|
||||
"to_table": self.quote_name(to_table),
|
||||
"to_column": self.quote_name(to_column),
|
||||
}
|
||||
elif self.connection.features.supports_foreign_keys:
|
||||
self.deferred_sql.append(self._create_fk_sql(model, field, "_fk_%(to_table)s_%(to_column)s"))
|
||||
# Add the SQL to our big list
|
||||
column_sqls.append("%s %s" % (
|
||||
self.quote_name(field.column),
|
||||
definition,
|
||||
))
|
||||
# Autoincrement SQL (for backends with post table definition variant)
|
||||
if field.get_internal_type() in ("AutoField", "BigAutoField"):
|
||||
autoinc_sql = self.connection.ops.autoinc_sql(model._meta.db_table, field.column)
|
||||
if autoinc_sql:
|
||||
self.deferred_sql.extend(autoinc_sql)
|
||||
|
||||
# Add any unique_togethers (always deferred, as some fields might be
|
||||
# created afterwards, like geometry fields with some backends)
|
||||
for fields in model._meta.unique_together:
|
||||
columns = [model._meta.get_field(field).column for field in fields]
|
||||
self.deferred_sql.append(self._create_unique_sql(model, columns))
|
||||
constraints = [constraint.constraint_sql(model, self) for constraint in model._meta.constraints]
|
||||
# Make the table
|
||||
sql = self.sql_create_table % {
|
||||
"table": self.quote_name(model._meta.db_table),
|
||||
"definition": ", ".join(constraint for constraint in (*column_sqls, *constraints) if constraint),
|
||||
}
|
||||
if model._meta.db_tablespace:
|
||||
tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
|
||||
if tablespace_sql:
|
||||
sql += ' ' + tablespace_sql
|
||||
sql, params = self.table_sql(model)
|
||||
# Prevent using [] as params, in the case a literal '%' is used in the definition
|
||||
self.execute(sql, params or None)
|
||||
|
||||
|
|
Loading…
Reference in New Issue