summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Golding-Day <rob@golding-day.com>2019-05-05 16:26:06 -0400
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-05-07 10:28:14 +0200
commit4043dc69cd41d100f201e4c71b1515db341fbd45 (patch)
treee0b046d238f2861441310a4ef0be4c4b9d80c72a
parent0e2ed4fdd197dae1da2553111034e92e10b30c41 (diff)
Fixed #30444 -- Moved SQL generation for tables to BaseDatabaseSchemaEditor.table_sql().
-rw-r--r--AUTHORS1
-rw-r--r--django/db/backends/base/schema.py112
2 files changed, 59 insertions, 54 deletions
diff --git a/AUTHORS b/AUTHORS
index e9c027167c..da44e980e4 100644
--- a/AUTHORS
+++ b/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>
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index 1280666924..990a7f55fb 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -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)