From ea880ec233ecd61c20b74eb7d6d1cf1223897179 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 22 Aug 2020 14:32:01 -0400 Subject: [PATCH] Fixed #24533 -- Dropped PostgreSQL sequence and Oracle identity when migrating away from AutoField. --- django/db/backends/oracle/schema.py | 11 +++++++++++ django/db/backends/postgresql/schema.py | 13 +++++++++++++ tests/schema/tests.py | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/django/db/backends/oracle/schema.py b/django/db/backends/oracle/schema.py index d6585a80ca..002cb9e48b 100644 --- a/django/db/backends/oracle/schema.py +++ b/django/db/backends/oracle/schema.py @@ -122,6 +122,17 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): # Rename and possibly make the new field NOT NULL super().alter_field(model, new_temp_field, new_field) + def _alter_column_type_sql(self, model, old_field, new_field, new_type): + auto_field_types = {'AutoField', 'BigAutoField', 'SmallAutoField'} + # Drop the identity if migrating away from AutoField. + if ( + old_field.get_internal_type() in auto_field_types and + new_field.get_internal_type() not in auto_field_types and + self._is_identity_column(model._meta.db_table, new_field.column) + ): + self._drop_identity(model._meta.db_table, new_field.column) + return super()._alter_column_type_sql(model, old_field, new_field, new_type) + def normalize_name(self, name): """ Get the properly shortened and uppercased identifier as returned by diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index e77915b3b1..b2442f80b7 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -155,6 +155,19 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): ), ], ) + elif old_field.db_parameters(connection=self.connection)['type'] in serial_fields_map: + # Drop the sequence if migrating away from AutoField. + column = strip_quotes(new_field.column) + sequence_name = '%s_%s_seq' % (table, column) + fragment, _ = super()._alter_column_type_sql(model, old_field, new_field, new_type) + return fragment, [ + ( + self.sql_delete_sequence % { + 'sequence': self.quote_name(sequence_name), + }, + [], + ), + ] else: return super()._alter_column_type_sql(model, old_field, new_field, new_type) diff --git a/tests/schema/tests.py b/tests/schema/tests.py index e516b17b59..8e992b4917 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -677,6 +677,11 @@ class SchemaTests(TransactionTestCase): new_field.model = Author with connection.schema_editor() as editor: editor.alter_field(Author, old_field, new_field, strict=True) + # Now that ID is an IntegerField, the database raises an error if it + # isn't provided. + if not connection.features.supports_unspecified_pk: + with self.assertRaises(DatabaseError): + Author.objects.create() def test_alter_auto_field_to_char_field(self): # Create the table