diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index 9384c5e3b2..6a65d12415 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -42,7 +42,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): def _field_data_type(self, field): if field.is_relation: return field.rel_db_type(self.connection) - return self.connection.data_types[field.get_internal_type()] + return self.connection.data_types.get( + field.get_internal_type(), + field.db_type(self.connection), + ) def _create_like_index_sql(self, model, field): """ diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 4f3c2b361b..08a77000b2 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -875,6 +875,26 @@ class SchemaTests(TransactionTestCase): with self.assertRaisesMessage(DataError, msg): editor.alter_field(Author, old_field, new_field, strict=True) + @unittest.skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific') + def test_alter_field_with_custom_db_type(self): + from django.contrib.postgres.fields import ArrayField + + class Foo(Model): + field = ArrayField(CharField(max_length=255)) + + class Meta: + app_label = 'schema' + + with connection.schema_editor() as editor: + editor.create_model(Foo) + self.isolated_local_models = [Foo] + old_field = Foo._meta.get_field('field') + new_field = ArrayField(CharField(max_length=16)) + new_field.set_attributes_from_name('field') + new_field.model = Foo + with connection.schema_editor() as editor: + editor.alter_field(Foo, old_field, new_field, strict=True) + def test_alter_textfield_to_null(self): """ #24307 - Should skip an alter statement on databases with