summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIuri de Silvio <iurisilvio@gmail.com>2020-07-25 10:42:43 -0300
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-08-14 13:13:36 +0200
commit632ccffc49658de5348c51a8918719364be54f37 (patch)
treed1bb2b18bb14c6338c30477860d3c4d9d042522f
parent3a6fa1d962ad9bd5678290bc22dd35bff13eb1f5 (diff)
Fixed #31826 -- Made AlterField operation a noop when adding db_column.
AlterField operation with adding a db_column is a noop if the column name is not changed.
-rw-r--r--django/db/backends/base/schema.py10
-rw-r--r--tests/migrations/test_operations.py53
2 files changed, 61 insertions, 2 deletions
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index d988fca903..d833f508e5 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -1037,10 +1037,16 @@ class BaseDatabaseSchemaEditor:
return output
def _field_should_be_altered(self, old_field, new_field):
- # Don't alter when changing only a field name.
+ _, old_path, old_args, old_kwargs = old_field.deconstruct()
+ _, new_path, new_args, new_kwargs = new_field.deconstruct()
+ # Don't alter when:
+ # - changing only a field name
+ # - adding only a db_column and the column name is not changed
+ old_kwargs.pop('db_column', None)
+ new_kwargs.pop('db_column', None)
return (
old_field.column != new_field.column or
- old_field.deconstruct()[1:] != new_field.deconstruct()[1:]
+ (old_path, old_args, old_kwargs) != (new_path, new_args, new_kwargs)
)
def _field_should_be_indexed(self, model, field):
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 6abbd34ab8..0ebb8ff0a3 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -1354,6 +1354,59 @@ class OperationTests(OperationTestBase):
self.assertEqual(definition[1], [])
self.assertEqual(sorted(definition[2]), ["field", "model_name", "name"])
+ def test_alter_field_add_db_column_noop(self):
+ """
+ AlterField operation is a noop when adding only a db_column and the
+ column name is not changed.
+ """
+ app_label = 'test_afadbn'
+ project_state = self.set_up_test_model(app_label, related_model=True)
+ pony_table = '%s_pony' % app_label
+ new_state = project_state.clone()
+ operation = migrations.AlterField('Pony', 'weight', models.FloatField(db_column='weight'))
+ operation.state_forwards(app_label, new_state)
+ self.assertIsNone(
+ project_state.models[app_label, 'pony'].fields['weight'].db_column,
+ )
+ self.assertEqual(
+ new_state.models[app_label, 'pony'].fields['weight'].db_column,
+ 'weight',
+ )
+ self.assertColumnExists(pony_table, 'weight')
+ with connection.schema_editor() as editor:
+ with self.assertNumQueries(0):
+ operation.database_forwards(app_label, editor, project_state, new_state)
+ self.assertColumnExists(pony_table, 'weight')
+ with connection.schema_editor() as editor:
+ with self.assertNumQueries(0):
+ operation.database_backwards(app_label, editor, new_state, project_state)
+ self.assertColumnExists(pony_table, 'weight')
+
+ rider_table = '%s_rider' % app_label
+ new_state = project_state.clone()
+ operation = migrations.AlterField(
+ 'Rider',
+ 'pony',
+ models.ForeignKey('Pony', models.CASCADE, db_column='pony_id'),
+ )
+ operation.state_forwards(app_label, new_state)
+ self.assertIsNone(
+ project_state.models[app_label, 'rider'].fields['pony'].db_column,
+ )
+ self.assertIs(
+ new_state.models[app_label, 'rider'].fields['pony'].db_column,
+ 'pony_id',
+ )
+ self.assertColumnExists(rider_table, 'pony_id')
+ with connection.schema_editor() as editor:
+ with self.assertNumQueries(0):
+ operation.database_forwards(app_label, editor, project_state, new_state)
+ self.assertColumnExists(rider_table, 'pony_id')
+ with connection.schema_editor() as editor:
+ with self.assertNumQueries(0):
+ operation.database_forwards(app_label, editor, new_state, project_state)
+ self.assertColumnExists(rider_table, 'pony_id')
+
def test_alter_field_pk(self):
"""
Tests the AlterField operation on primary keys (for things like PostgreSQL's SERIAL weirdness)