From 27375ad50ea3306844aab8122de13e9b3e0d1189 Mon Sep 17 00:00:00 2001 From: lufafajoshua <77637648+lufafajoshua@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:37:05 +0300 Subject: [PATCH] Fixed #35969 -- Disallowed specifying a USING clause for altered generated field. PostgreSQL versions 16.5 and above no longer permit the use of a USING clause when changing the type of a generated column. --- django/db/backends/postgresql/schema.py | 2 ++ tests/migrations/test_operations.py | 31 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index 75bf331472..964009988c 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -120,6 +120,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): return None def _using_sql(self, new_field, old_field): + if new_field.generated: + return "" using_sql = " USING %(column)s::%(type)s" new_internal_type = new_field.get_internal_type() old_internal_type = old_field.get_internal_type() diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index 33a7b6dc3d..d95e382285 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -6415,6 +6415,37 @@ class OperationTests(OperationTestBase): operation.database_backwards(app_label, editor, new_state, project_state) self.assertColumnNotExists(f"{app_label}_pony", "modified_pink") + @skipUnlessDBFeature("supports_stored_generated_columns") + def test_generated_field_changes_output_field(self): + app_label = "test_gfcof" + operation = migrations.AddField( + "Pony", + "modified_pink", + models.GeneratedField( + expression=F("pink") + F("pink"), + output_field=models.IntegerField(), + db_persist=True, + ), + ) + from_state, to_state = self.make_test_state(app_label, operation) + # Add generated column. + with connection.schema_editor() as editor: + operation.database_forwards(app_label, editor, from_state, to_state) + # Update output_field used in the generated field. + operation = migrations.AlterField( + "Pony", + "modified_pink", + models.GeneratedField( + expression=F("pink") + F("pink"), + output_field=models.DecimalField(decimal_places=2, max_digits=16), + db_persist=True, + ), + ) + from_state = to_state.clone() + to_state = self.apply_operations(app_label, from_state, [operation]) + with connection.schema_editor() as editor: + operation.database_forwards(app_label, editor, from_state, to_state) + @skipUnlessDBFeature("supports_stored_generated_columns") def test_add_generated_field_stored(self): self._test_add_generated_field(db_persist=True)