mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
[5.0.x] Fixed #35625 -- Fixed a crash when adding a field with db_default and check constraint.
This is the exact same issue as refs #30408 but for creating a model with a
constraint containing % escapes instead of column addition. All of these issues
stem from a lack of SQL and parameters separation from the BaseConstraint DDL
generating methods preventing them from being mixed with other parts of the
schema alteration logic that do make use of parametrization on some backends
(e.g. Postgres, MySQL for DEFAULT).
Prior to the addition of Field.db_default and GeneratedField in 5.0
parametrization of DDL was never exercised on model creation so this is
effectively a bug with db_default as the GeneratedField case was addressed by
refs #35336.
Thanks Julien Chaumont for the report and Mariusz Felisiak for the review.
Backport of f359990e49 from main.
This commit is contained in:
committed by
Sarah Boyce
parent
68f65630c6
commit
41d8ef18ac
@@ -164,7 +164,7 @@ class BaseDatabaseSchemaEditor:
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
if exc_type is None:
|
||||
for sql in self.deferred_sql:
|
||||
self.execute(sql)
|
||||
self.execute(sql, None)
|
||||
if self.atomic_migration:
|
||||
self.atomic.__exit__(exc_type, exc_value, traceback)
|
||||
|
||||
@@ -265,16 +265,29 @@ class BaseDatabaseSchemaEditor:
|
||||
)
|
||||
if autoinc_sql:
|
||||
self.deferred_sql.extend(autoinc_sql)
|
||||
constraints = [
|
||||
constraint.constraint_sql(model, self)
|
||||
for constraint in model._meta.constraints
|
||||
]
|
||||
# The BaseConstraint DDL creation methods such as constraint_sql(),
|
||||
# create_sql(), and delete_sql(), were not designed in a way that
|
||||
# separate SQL from parameters which make their generated SQL unfit to
|
||||
# be used in a context where parametrization is delegated to the
|
||||
# backend.
|
||||
constraint_sqls = []
|
||||
if params:
|
||||
# If parameters are present (e.g. a DEFAULT clause on backends that
|
||||
# allow parametrization) defer constraint creation so they are not
|
||||
# mixed with SQL meant to be parametrized.
|
||||
for constraint in model._meta.constraints:
|
||||
self.deferred_sql.append(constraint.create_sql(model, self))
|
||||
else:
|
||||
constraint_sqls.extend(
|
||||
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(
|
||||
str(constraint)
|
||||
for constraint in (*column_sqls, *constraints)
|
||||
if constraint
|
||||
str(statement)
|
||||
for statement in (*column_sqls, *constraint_sqls)
|
||||
if statement
|
||||
),
|
||||
}
|
||||
if model._meta.db_tablespace:
|
||||
|
||||
Reference in New Issue
Block a user