Skip to content

Commit

Permalink
[3.2.x] Fixed #32832 -- Fixed adding BLOB/TEXT nullable field with de…
Browse files Browse the repository at this point in the history
…fault on MySQL 8.0.13+.

Regression in d4ac23b.

Thanks Omkar Deshpande for the report.

Backport of fa0433d from main
  • Loading branch information
felixxm committed Jun 10, 2021
1 parent bb29174 commit 826a165
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
11 changes: 9 additions & 2 deletions django/db/backends/base/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,14 @@ def column_sql(self, model, field, include_default=False):
# Work out nullability
null = field.null
# If we were told to include a default value, do so
include_default = include_default and not self.skip_default(field)
include_default = (
include_default and
not self.skip_default(field) and
# Don't include a default value if it's a nullable field and the
# default cannot be dropped in the ALTER COLUMN statement (e.g.
# MySQL longtext and longblob).
not (null and self.skip_default_on_alter(field))
)
if include_default:
default_value = self.effective_default(field)
column_default = ' DEFAULT ' + self._column_default_sql(field)
Expand Down Expand Up @@ -515,7 +522,7 @@ def add_field(self, model, field):
self.execute(sql, params)
# Drop the default if we need to
# (Django usually does not use in-database defaults)
if not self.skip_default(field) and self.effective_default(field) is not None:
if not self.skip_default_on_alter(field) and self.effective_default(field) is not None:
changes_sql, params = self._alter_column_default_sql(model, None, field, drop=True)
sql = self.sql_alter_column % {
"table": self.quote_name(model._meta.db_table),
Expand Down
4 changes: 4 additions & 0 deletions docs/releases/3.2.5.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ Bugfixes
* Fixed a bug in Django 3.2 that caused a migration crash on MySQL 8.0.13+ when
altering ``BinaryField``, ``JSONField``, or ``TextField`` to non-nullable
(:ticket:`32503`).

* Fixed a regression in Django 3.2 that caused a migration crash on MySQL
8.0.13+ when adding nullable ``BinaryField``, ``JSONField``, or ``TextField``
with a default value (:ticket:`32832`).
27 changes: 27 additions & 0 deletions tests/schema/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3131,6 +3131,33 @@ def test_add_field_default_nullable(self):
if connection.features.can_introspect_default:
self.assertIn(field.default, ['NULL', None])

def test_add_textfield_default_nullable(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
# Add new nullable TextField with a default.
new_field = TextField(blank=True, null=True, default='text')
new_field.set_attributes_from_name('description')
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
Author.objects.create(name='Anonymous1')
with connection.cursor() as cursor:
cursor.execute('SELECT description FROM schema_author;')
item = cursor.fetchall()[0]
self.assertIsNone(item[0])
field = next(
f
for f in connection.introspection.get_table_description(
cursor,
'schema_author',
)
if f.name == 'description'
)
# Field is still nullable.
self.assertTrue(field.null_ok)
# The database default is no longer set.
if connection.features.can_introspect_default:
self.assertIn(field.default, ['NULL', None])

def test_alter_field_default_dropped(self):
# Create the table
with connection.schema_editor() as editor:
Expand Down

0 comments on commit 826a165

Please sign in to comment.