diff options
| author | Yuekui Li <liyuekui@gmail.com> | 2021-05-19 16:30:15 -0700 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-06-10 20:01:38 +0200 |
| commit | 57146ba388b81aa9f7f47ad1dbca060871c9ca62 (patch) | |
| tree | 4c874536c6b7ccdc47731a91475e978a0001f81c | |
| parent | 9b096063c13085d06236a72dcc46915f4c4ec28a (diff) | |
[3.2.x] Fixed #32503 -- Fixed altering BLOB/TEXT field to non-nullable with default on MySQL 8.0.13+.
MySQL 8.0.13+ supports defaults for BLOB/TEXT but not in the
ALTER COLUMN statement.
Regression in 6b16c91157512587017e9178d066ed1a683e7795.
Thanks Matt Westcott for the report.
Backport of 5e04e84d67da8163f365e9f5fcd169e2630e2873 from main
| -rw-r--r-- | django/db/backends/base/schema.py | 9 | ||||
| -rw-r--r-- | django/db/backends/mysql/schema.py | 7 | ||||
| -rw-r--r-- | tests/schema/models.py | 1 | ||||
| -rw-r--r-- | tests/schema/tests.py | 9 |
4 files changed, 25 insertions, 1 deletions
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py index adaf6d7378..fa025ec0e8 100644 --- a/django/db/backends/base/schema.py +++ b/django/db/backends/base/schema.py @@ -266,6 +266,13 @@ class BaseDatabaseSchemaEditor: """ return False + def skip_default_on_alter(self, field): + """ + Some backends don't accept default values for certain columns types + (i.e. MySQL longtext and longblob) in the ALTER COLUMN statement. + """ + return False + def prepare_default(self, value): """ Only used for backends which have requires_literal_defaults feature @@ -721,7 +728,7 @@ class BaseDatabaseSchemaEditor: old_default = self.effective_default(old_field) new_default = self.effective_default(new_field) if ( - not self.skip_default(new_field) and + not self.skip_default_on_alter(new_field) and old_default != new_default and new_default is not None ): diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py index 9bbcffc899..39450dd50d 100644 --- a/django/db/backends/mysql/schema.py +++ b/django/db/backends/mysql/schema.py @@ -68,6 +68,13 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor): return self._is_limited_data_type(field) return False + def skip_default_on_alter(self, field): + if self._is_limited_data_type(field) and not self.connection.mysql_is_mariadb: + # MySQL doesn't support defaults for BLOB and TEXT in the + # ALTER COLUMN statement. + return True + return False + @property def _supports_limited_data_type_defaults(self): # MariaDB >= 10.2.1 and MySQL >= 8.0.13 supports defaults for BLOB diff --git a/tests/schema/models.py b/tests/schema/models.py index 6d4465807a..75e4de0874 100644 --- a/tests/schema/models.py +++ b/tests/schema/models.py @@ -158,6 +158,7 @@ class IntegerPK(models.Model): class Note(models.Model): info = models.TextField() + address = models.TextField(null=True) class Meta: apps = new_apps diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 4522f5faf4..8376c62528 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -778,6 +778,15 @@ class SchemaTests(TransactionTestCase): with connection.schema_editor() as editor: editor.alter_field(Note, old_field, new_field, strict=True) + def test_alter_text_field_to_not_null_with_default_value(self): + with connection.schema_editor() as editor: + editor.create_model(Note) + old_field = Note._meta.get_field('address') + new_field = TextField(blank=True, default='', null=False) + new_field.set_attributes_from_name('address') + with connection.schema_editor() as editor: + editor.alter_field(Note, old_field, new_field, strict=True) + @skipUnlessDBFeature('can_defer_constraint_checks', 'can_rollback_ddl') def test_alter_fk_checks_deferred_constraints(self): """ |
