Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#32832 closed Bug (fixed)

Adding nullable TextField/JSONField with default fails on MySQL 8.0.13+.

Reported by: Omkar Deshpande Owned by: Mariusz Felisiak
Component: Migrations Version: 3.2
Severity: Release blocker Keywords: django, mysql, textfield, JsonField
Cc: Adam Johnson, Mariusz Felisiak, Simon Charette, Jordan Bae Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Versions Involved:

Django: 3.2.4
Python: 3.8.7
MySQL: 8.0.19
OS: CentOS 7


Referenced:

Ticket: https://code.djangoproject.com/ticket/32503
PR: https://github.com/django/django/pull/14421
Commit: https://github.com/django/django/pull/14421/commits/5e04e84d67da8163f365e9f5fcd169e2630e2873


New project used for reproducing the error:

Project: https://github.com/omkar-dsd/almanac


Error:

django.db.utils.OperationalError: (1101, "BLOB, TEXT, GEOMETRY or JSON column 'new_txt' can't have a default value")

Occurred on migration:

migrations.AddField(
            model_name='nucleusdata',
            name='new_txt',
            field=models.TextField(blank=True, default='abc', null=True),
        )

How to reproduce:

  1. Add new TextField or JSONField with default on pre-existing model, with Django < 3.2
  2. Upgrade Django version to 3.2.4
  3. Run migration which involves creation of of the new field added in step 1.

Details:

This occurs for all JSON and Text Fields with default value.

This occurred to me when I upgraded from Django 2.2.24 to 3.2.4 and ran migrations on fresh DB.
This error did not occur when upgraded from Django 2.2.24 to 3.1.12. And, it occurs for all 3.2.X till date.
New project was created to demonstrate the issue it available on the above GitHub link for reference.

Attachments (6)

requirements.txt (97 bytes) - added by Omkar Deshpande 2 years ago.
Python Project Requirement
models.py (630 bytes) - added by Omkar Deshpande 2 years ago.
models.py
0001_initial.py (1.1 KB) - added by Omkar Deshpande 2 years ago.
Initial Migration to Create the Table
0002_auto_20210609_1553.py (998 bytes) - added by Omkar Deshpande 2 years ago.
Second Migration to Alter the fields
0003_nucleusdata_new_txt.py (414 bytes) - added by Omkar Deshpande 2 years ago.
Third Migration to AddField with default value on which migration breaks
django_AddField_error.txt (6.1 KB) - added by Omkar Deshpande 2 years ago.
Full Error Traceback

Download all attachments as: .zip

Change History (13)

Changed 2 years ago by Omkar Deshpande

Attachment: requirements.txt added

Python Project Requirement

Changed 2 years ago by Omkar Deshpande

Attachment: models.py added

models.py

Changed 2 years ago by Omkar Deshpande

Attachment: 0001_initial.py added

Initial Migration to Create the Table

Changed 2 years ago by Omkar Deshpande

Attachment: 0002_auto_20210609_1553.py added

Second Migration to Alter the fields

Changed 2 years ago by Omkar Deshpande

Attachment: 0003_nucleusdata_new_txt.py added

Third Migration to AddField with default value on which migration breaks

Changed 2 years ago by Omkar Deshpande

Attachment: django_AddField_error.txt added

Full Error Traceback

comment:1 Changed 2 years ago by Mariusz Felisiak

Cc: Simon Charette Jordan Bae added
Severity: NormalRelease blocker
Summary: AddField migration of TextField and JSONField fails on Django 3.2.X for MySQL 8.0.19Adding nullable TextField/JSONField with default fails on MySQL 8.0.13+.

Regression in d4ac23bee1c84d8e4610350202ac068fc90f38c0.
Reproduced at fcd44b889f36c4be87910745614a0a4c88d7a3d8.

We can consider backporting 5e04e84d67da8163f365e9f5fcd169e2630e2873 and fix it with:

diff --git a/django/db/backends/base/schema.py b/django/db/backends/base/schema.py
index c409464eca..77c5ce1629 100644
--- a/django/db/backends/base/schema.py
+++ b/django/db/backends/base/schema.py
@@ -900,7 +900,7 @@ class BaseDatabaseSchemaEditor:
 
         new_db_params = new_field.db_parameters(connection=self.connection)
         if drop:
-            if new_field.null:
+            if new_field.null and not self.skip_default_on_alter(new_field):
                 sql = self.sql_alter_column_no_default_null
             else:
                 sql = self.sql_alter_column_no_default

comment:2 Changed 2 years ago by Mariusz Felisiak

Omkar, thanks for the detailed report!

comment:3 Changed 2 years ago by Mariusz Felisiak

Triage Stage: UnreviewedAccepted

comment:4 Changed 2 years ago by Mariusz Felisiak

Owner: changed from nobody to Mariusz Felisiak
Status: newassigned

comment:5 Changed 2 years ago by Mariusz Felisiak

Has patch: set

comment:6 Changed 2 years ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In fa0433d0:

Fixed #32832 -- Fixed adding BLOB/TEXT nullable field with default on MySQL 8.0.13+.

Regression in d4ac23bee1c84d8e4610350202ac068fc90f38c0.

Thanks Omkar Deshpande for the report.

comment:7 Changed 2 years ago by Mariusz Felisiak <felisiak.mariusz@…>

In 826a1659:

[3.2.x] Fixed #32832 -- Fixed adding BLOB/TEXT nullable field with default on MySQL 8.0.13+.

Regression in d4ac23bee1c84d8e4610350202ac068fc90f38c0.

Thanks Omkar Deshpande for the report.

Backport of fa0433d05f213afe4c67055006320f7aba4c8108 from main

Note: See TracTickets for help on using tickets.
Back to Top