Skip to content

Commit

Permalink
Fixed #32503 -- Fixed altering BLOB/TEXT field to non-nullable with d…
Browse files Browse the repository at this point in the history
…efault on MySQL 8.0.13+.

MySQL 8.0.13+ supports defaults for BLOB/TEXT but not in the
ALTER COLUMN statement.

Regression in 6b16c91.

Thanks Matt Westcott for the report.
  • Loading branch information
yuekui authored and felixxm committed May 21, 2021
1 parent 7cca229 commit 5e04e84
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 1 deletion.
9 changes: 8 additions & 1 deletion django/db/backends/base/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ def skip_default(self, field):
"""
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
Expand Down Expand Up @@ -721,7 +728,7 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type,
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
):
Expand Down
7 changes: 7 additions & 0 deletions django/db/backends/mysql/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ def skip_default(self, field):
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
Expand Down
1 change: 1 addition & 0 deletions tests/schema/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ class Meta:

class Note(models.Model):
info = models.TextField()
address = models.TextField(null=True)

class Meta:
apps = new_apps
Expand Down
9 changes: 9 additions & 0 deletions tests/schema/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,15 @@ def test_alter_text_field(self):
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):
"""
Expand Down

0 comments on commit 5e04e84

Please sign in to comment.