Opened 7 years ago

Closed 7 years ago

#29103 closed Bug (fixed)

sqlmigrate produces byte literal in SQL for one-off string default value in TextField, CharField on MySQL

Reported by: Qlimax Owned by: nobody
Component: Migrations Version: 2.0
Severity: Normal Keywords: sqlmigrate, byte, default value, one-off
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

$ python manage.py makemigrations myapp
You are trying to add a non-nullable field 'text1' to mytable without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
>>> ''
Migrations for 'myapp':
  myapp/migrations/0003_somechange.py
    - Add field text1 to mytable

Done.

$ python manage.py sqlmigrate myapp 0003_somechange 
BEGIN;
--
-- Add field text1 to mytable
--
ALTER TABLE `myapp_mytable` ADD COLUMN `text1` longtext NOT NULL;
UPDATE `myapp_mytable` SET `text1` = b"''";
COMMIT;

$ cat myapp/migrations/0003_somechange.py 
# Generated by Django 2.0.2 on 2018-02-02 11:56

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0002_auto_20180202_1154'),
    ]

    operations = [
        migrations.AddField(
            model_name='mytable',
            name='text1',
            field=models.TextField(default=''),
            preserve_default=False,
        ),
    ]
$ python --version
Python 3.4.2

Change History (7)

comment:1 by Qlimax, 7 years ago

Summary: sqlmigrate produces byte literal in SQL for one-off empty string default value in TextField, CharFieldsqlmigrate produces byte literal in SQL for one-off string default value in TextField, CharField

comment:2 by Tim Graham, 7 years ago

Easy pickings: unset
Summary: sqlmigrate produces byte literal in SQL for one-off string default value in TextField, CharFieldsqlmigrate produces byte literal in SQL for one-off string default value in TextField, CharField on MySQL
Triage Stage: UnreviewedAccepted

This is MySQL-specific. I couldn't quickly locate where the problem is.

comment:3 by Claude Paroz, 7 years ago

Has patch: set

comment:4 by Claude Paroz, 7 years ago

It's still not entirely clear to me what is the correct expected output. I think that internally, mysqlclient is using the 'surrogateescape' encoding which is apparently not usable for some outputs like the shell. Any suggestion welcome.

comment:5 by Claude Paroz, 7 years ago

Ah sorry, in the current use case, the expected output is simply no binary marker, which is fixed in my patch.
My question is about the SQL output in the hypothetic case the default would be a real binary bytestring.

comment:6 by Carlton Gibson, 7 years ago

Triage Stage: AcceptedReady for checkin

comment:7 by Tim Graham <timograham@…>, 7 years ago

Resolution: fixed
Status: newclosed

In 3c4ff217:

Fixed #29103 -- Removed bad 'b'-prefix added by MySQL's SchemaEditor.quote_value().

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