summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuekui Li <liyuekui@gmail.com>2021-05-19 16:30:15 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-05-21 13:34:37 +0200
commit5e04e84d67da8163f365e9f5fcd169e2630e2873 (patch)
tree95b7951434e823a12ac50177ae5f6bf828a4dd92
parent7cca22964c09e8dafc313a400c428242404d527a (diff)
downloaddjango-5e04e84d67da8163f365e9f5fcd169e2630e2873.tar.gz
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.
-rw-r--r--django/db/backends/base/schema.py9
-rw-r--r--django/db/backends/mysql/schema.py7
-rw-r--r--tests/schema/models.py1
-rw-r--r--tests/schema/tests.py9
4 files changed, 25 insertions, 1 deletions
diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index 4998a3fe2e..ad2f5a7da1 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 8587d2b15d..c5f5bd2e85 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):
"""