Fixed #27928 -- Avoided SET/DROP DEFAULT unless a field changes from null to non-null.

Thanks Christophe Pettus, Matteo Pietro Russo for reports and Tim for review.
This commit is contained in:
Simon Charette 2017-03-31 18:42:08 -04:00
parent 5e710cf4a5
commit 35c0025151
2 changed files with 17 additions and 0 deletions

View File

@ -578,6 +578,8 @@ class BaseDatabaseSchemaEditor:
old_default = self.effective_default(old_field)
new_default = self.effective_default(new_field)
needs_database_default = (
old_field.null and
not new_field.null and
old_default != new_default and
new_default is not None and
not self.skip_default(new_field)

View File

@ -1956,6 +1956,21 @@ class SchemaTests(TransactionTestCase):
if connection.features.can_introspect_default:
self.assertIsNone(field.default)
@unittest.skipIf(connection.vendor == 'sqlite', 'SQLite naively remakes the table on field alteration.')
def test_alter_field_default_doesnt_perfom_queries(self):
"""
No queries are performed if a field default changes and the field's
not changing from null to non-null.
"""
with connection.schema_editor() as editor:
editor.create_model(AuthorWithDefaultHeight)
old_field = AuthorWithDefaultHeight._meta.get_field('height')
new_default = old_field.default * 2
new_field = PositiveIntegerField(null=True, blank=True, default=new_default)
new_field.set_attributes_from_name('height')
with connection.schema_editor() as editor, self.assertNumQueries(0):
editor.alter_field(AuthorWithDefaultHeight, old_field, new_field, strict=True)
def test_add_textfield_unhashable_default(self):
# Create the table
with connection.schema_editor() as editor: