[1.7.x] Fixed #23581 -- Prevented extraneous DROP DEFAULT statements.

Thanks john_scott for the report and Markus Holtermann for review.

Backport of ab4f709da4 from master
This commit is contained in:
Tim Graham 2014-12-29 16:23:18 -05:00
parent 79645529e7
commit a9da5dd5b6
3 changed files with 26 additions and 23 deletions

View File

@ -534,34 +534,31 @@ class BaseDatabaseSchemaEditor(object):
# Default change?
old_default = self.effective_default(old_field)
new_default = self.effective_default(new_field)
if old_default != new_default and not self.skip_default(new_field):
if new_default is None:
needs_database_default = (
old_default != new_default and
new_default is not None and
not self.skip_default(new_field)
)
if needs_database_default:
if self.connection.features.requires_literal_defaults:
# Some databases can't take defaults as a parameter (oracle)
# If this is the case, the individual schema backend should
# implement prepare_default
actions.append((
self.sql_alter_column_no_default % {
self.sql_alter_column_default % {
"column": self.quote_name(new_field.column),
"default": self.prepare_default(new_default),
},
[],
))
else:
if self.connection.features.requires_literal_defaults:
# Some databases can't take defaults as a parameter (oracle)
# If this is the case, the individual schema backend should
# implement prepare_default
actions.append((
self.sql_alter_column_default % {
"column": self.quote_name(new_field.column),
"default": self.prepare_default(new_default),
},
[],
))
else:
actions.append((
self.sql_alter_column_default % {
"column": self.quote_name(new_field.column),
"default": "%s",
},
[new_default],
))
actions.append((
self.sql_alter_column_default % {
"column": self.quote_name(new_field.column),
"default": "%s",
},
[new_default],
))
# Nullability change?
if old_field.null != new_field.null:
if new_field.null:
@ -696,7 +693,7 @@ class BaseDatabaseSchemaEditor(object):
)
# Drop the default if we need to
# (Django usually does not use in-database defaults)
if not self.skip_default(new_field) and new_field.default is not None:
if needs_database_default:
sql = self.sql_alter_column % {
"table": self.quote_name(model._meta.db_table),
"changes": self.sql_alter_column_no_default % {

View File

@ -181,3 +181,5 @@ Bugfixes
* Supported strings escaped by third-party libraries with the ``__html__``
convention in the template engine (:ticket:`23831`).
* Prevented extraneous ``DROP DEFAULT`` SQL in migrations (:ticket:`23581`).

View File

@ -554,6 +554,10 @@ class SchemaTests(TransactionTestCase):
strict=True,
)
# This will fail if DROP DEFAULT is inadvertently executed on this
# field which drops the id sequence, at least on PostgreSQL.
Author.objects.create(name='Foo')
def test_rename(self):
"""
Tests simple altering of fields