#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 , 9 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:2 by , 9 years ago
I got the buggy behaviour on Django 1.7.10. Are you using the same version?
comment:3 by , 9 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 , 9 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 , 9 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.