[Django] #25332: migrate fails for CharField if max_length is omitted

141 views
Skip to first unread message

Django

unread,
Sep 1, 2015, 7:20:48 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
----------------------------+------------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.7
Severity: Normal | Keywords: max_length CharField migrate
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+------------------------------------------
When adding a CharField to model and leaving out max_length undefined
Django migration is created but fails when is run.

Consider this model:


{{{
class Order(Model):
foo = models.DateField(verbose_name=_("Foo"))
}}}

We change it to this:

{{{
class Order(Model):
foo = models.DateField(verbose_name=_("Foo"))
payment_terms = models.CharField(verbose_name=_("Payment terms"),
blank=True)
}}}
note that I omit max_length parameter. I run makemigrations for my app,
the migration is created with the following operation:

{{{
migrations.AddField(
model_name='order',
name='payment_terms',
field=models.CharField(verbose_name='Payment terms',
blank=True),
preserve_default=True,
)
}}}

When I run the migration, it spits the following error:
{{{
File "/usr/lib/python3.4/runpy.py", line 182, in run_module
return _run_module_code(code, init_globals, run_name, mod_spec)
File "/usr/lib/python3.4/runpy.py", line 96, in _run_module_code
mod_name, mod_spec, pkg_name, script_name)
File "/usr/lib/python3.4/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/ryselis/PycharmProjects/ez_demo/manage.py", line 14, in
<module>
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/__init__.py", line 385, in
execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.4/dist-
packages/django/core/management/commands/migrate.py", line 161, in handle
executor.migrate(targets, plan, fake=options.get("fake", False))
File "/usr/local/lib/python3.4/dist-
packages/django/db/migrations/executor.py", line 68, in migrate
self.apply_migration(migration, fake=fake)
File "/usr/local/lib/python3.4/dist-
packages/django/db/migrations/executor.py", line 102, in apply_migration
migration.apply(project_state, schema_editor)
File "/usr/local/lib/python3.4/dist-
packages/django/db/migrations/migration.py", line 108, in apply
operation.database_forwards(self.app_label, schema_editor,
project_state, new_state)
File "/usr/local/lib/python3.4/dist-
packages/django/db/migrations/operations/fields.py", line 37, in
database_forwards
field,
File "/usr/local/lib/python3.4/dist-
packages/mysql/connector/django/schema.py", line 49, in add_field
super(DatabaseSchemaEditor, self).add_field(model, field)
File "/usr/local/lib/python3.4/dist-
packages/django/db/backends/schema.py", line 388, in add_field
self.execute(sql, params)
File "/usr/local/lib/python3.4/dist-
packages/django/db/backends/schema.py", line 111, in execute
cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-
packages/django/db/backends/utils.py", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/usr/local/lib/python3.4/dist-
packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.4/dist-
packages/mysql/connector/django/base.py", line 133, in execute
return self._execute_wrapper(self.cursor.execute, query, args)
File "/usr/local/lib/python3.4/dist-
packages/mysql/connector/django/base.py", line 116, in _execute_wrapper
utils.ProgrammingError(err.msg), sys.exc_info()[2])
File "/usr/local/lib/python3.4/dist-packages/django/utils/six.py", line
658, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.4/dist-
packages/mysql/connector/django/base.py", line 113, in _execute_wrapper
return method(query, args)
File "/usr/local/lib/python3.4/dist-packages/mysql/connector/cursor.py",
line 507, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/usr/local/lib/python3.4/dist-
packages/mysql/connector/connection.py", line 720, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/usr/local/lib/python3.4/dist-
packages/mysql/connector/connection.py", line 638, in _handle_result
raise errors.get_exception(packet)
django.db.utils.ProgrammingError: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the
right syntax to use near 'None) DEFAULT '' NOT NULL' at line 1
}}}

The SQL generated is

{{{
ALTER TABLE `myapp_order` ADD COLUMN `payment_terms` varchar(None) DEFAULT
'' NOT NULL
}}}

The docs say that "The max_length is enforced at the database level and in
Django’s validation."

I suppose this is not the correct behaviour. It used to generate a
reasonable error messsage in earlier Django versions.

--
Ticket URL: <https://code.djangoproject.com/ticket/25332>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Sep 1, 2015, 7:56:31 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
-------------------------------------+-------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.7
Severity: Normal | Resolution:
| worksforme
Keywords: max_length | Triage Stage:
CharField migrate | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* status: new => closed
* needs_better_patch: => 0
* resolution: => worksforme
* needs_tests: => 0
* needs_docs: => 0


Comment:

I couldn't reproduce this.
{{{
$ python manage.py makemigrations
SystemCheckError: System check identified some issues:

ERRORS:
app.Order.payment_terms: (fields.E120) CharFields must define a
'max_length' attribute.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25332#comment:1>

Django

unread,
Sep 1, 2015, 7:59:03 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
-------------------------------------+-------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
| worksforme
Keywords: max_length | Triage Stage:
CharField migrate | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ryselis):

I got the buggy behaviour on Django 1.7.10. Are you using the same
version?

--
Ticket URL: <https://code.djangoproject.com/ticket/25332#comment:2>

Django

unread,
Sep 1, 2015, 8:04:32 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
-------------------------------------+-------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
| worksforme
Keywords: max_length | Triage Stage:
CharField migrate | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ryselis):

This is my output for the same command:

{{{
$ python3 manage.py makemigrations myapp
Migrations for 'myapp':
0039_auto_20150901_1502.py:
- Add field payment_terms to order
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25332#comment:3>

Django

unread,
Sep 1, 2015, 9:08:36 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
-------------------------------------+-------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
| worksforme
Keywords: max_length | Triage Stage:
CharField migrate | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by timgraham):

Yes, I tested with the 1.7 branch.
[https://github.com/django/django/blob/c0f9957cea3366d0db64bad5fcb41203f5ebc3b9/django/db/models/fields/__init__.py#L1020-L1044
Here's the relevant code]. Could you try to debug why it's not being
called in your case?

--
Ticket URL: <https://code.djangoproject.com/ticket/25332#comment:4>

Django

unread,
Sep 1, 2015, 9:21:54 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
-------------------------------------+-------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
| worksforme
Keywords: max_length | Triage Stage:
CharField migrate | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by ryselis):

I have put a print on top of the method you have shown me. It is called
for some fields, but not the others. It looks like it works for all Django
built-in fields (those in contenttypes, auth), also other python libs that
are built on top of Django, but for my project there are fields for one
app only. It might be either problem with my project or some
configuration. I have searched through code and found out that the checks
are registered to the registry and then called. Could you point me to the
code that registers this check?

--
Ticket URL: <https://code.djangoproject.com/ticket/25332#comment:5>

Django

unread,
Sep 1, 2015, 9:30:57 AM9/1/15
to django-...@googlegroups.com
#25332: migrate fails for CharField if max_length is omitted
-------------------------------------+-------------------------------------
Reporter: ryselis | Owner: nobody
Type: Bug | Status: closed
Component: Migrations | Version: 1.7

Severity: Normal | Resolution:
| worksforme
Keywords: max_length | Triage Stage:
CharField migrate | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by timgraham):

[https://github.com/django/django/blob/c0f9957cea3366d0db64bad5fcb41203f5ebc3b9/django/core/checks/model_checks.py#L11-L29
Here you go] -- `model.check()` then calls `model._check_fields()`.

--
Ticket URL: <https://code.djangoproject.com/ticket/25332#comment:6>

Reply all
Reply to author
Forward
0 new messages