#25332 closed Bug (worksforme)
migrate fails for CharField if max_length is omitted
| Reported by: | Karolis Ryselis | Owned by: | nobody |
|---|---|---|---|
| Component: | Migrations | Version: | 1.7 |
| Severity: | Normal | Keywords: | max_length CharField migrate |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
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.
Change History (6)
comment:1 by , 10 years ago
| Resolution: | → worksforme |
|---|---|
| Status: | new → closed |
comment:2 by , 10 years ago
I got the buggy behaviour on Django 1.7.10. Are you using the same version?
comment:3 by , 10 years ago
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
comment:4 by , 10 years ago
Yes, I tested with the 1.7 branch. Here's the relevant code. Could you try to debug why it's not being called in your case?
comment:5 by , 10 years ago
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?
I couldn't reproduce this.