diff options
author | Hasan Ramezani <hasan.r67@gmail.com> | 2019-09-28 02:46:18 +0200 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-10-17 12:50:53 +0200 |
commit | ef4beafa2ce58a81a56ffd48a20a6153126b611a (patch) | |
tree | ea90b74c6307f51accc0f5d13d5e69d1e96b4b64 /django/db/backends/postgresql/schema.py | |
parent | 6f82df69efa372fb4bddf272fff577850a09f1dc (diff) | |
download | django-ef4beafa2ce58a81a56ffd48a20a6153126b611a.tar.gz |
Refs #28816 -- Prevented silencing data loss when decreasing CharField.max_length for ArrayField.base_field on PostgreSQL.
Diffstat (limited to 'django/db/backends/postgresql/schema.py')
-rw-r--r-- | django/db/backends/postgresql/schema.py | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/django/db/backends/postgresql/schema.py b/django/db/backends/postgresql/schema.py index 6a65d12415..cf90bb8f81 100644 --- a/django/db/backends/postgresql/schema.py +++ b/django/db/backends/postgresql/schema.py @@ -47,6 +47,13 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): field.db_type(self.connection), ) + def _field_base_data_types(self, field): + # Yield base data types for array fields. + if field.base_field.get_internal_type() == 'ArrayField': + yield from self._field_base_data_types(field.base_field) + else: + yield self._field_data_type(field.base_field) + def _create_like_index_sql(self, model, field): """ Return the statement to create an index with varchar operator pattern @@ -72,8 +79,15 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): def _alter_column_type_sql(self, model, old_field, new_field, new_type): self.sql_alter_column_type = 'ALTER COLUMN %(column)s TYPE %(type)s' # Cast when data type changed. - if self._field_data_type(old_field) != self._field_data_type(new_field): - self.sql_alter_column_type += ' USING %(column)s::%(type)s' + using_sql = ' USING %(column)s::%(type)s' + new_internal_type = new_field.get_internal_type() + old_internal_type = old_field.get_internal_type() + if new_internal_type == 'ArrayField' and new_internal_type == old_internal_type: + # Compare base data types for array fields. + if list(self._field_base_data_types(old_field)) != list(self._field_base_data_types(new_field)): + self.sql_alter_column_type += using_sql + elif self._field_data_type(old_field) != self._field_data_type(new_field): + self.sql_alter_column_type += using_sql # Make ALTER TYPE with SERIAL make sense. table = strip_quotes(model._meta.db_table) serial_fields_map = {'bigserial': 'bigint', 'serial': 'integer', 'smallserial': 'smallint'} |