Opened 6 years ago

Last modified 6 years ago

#29344 closed Bug

RemoveField on model with a single field — at Version 2

Reported by: Shadi Akiki Owned by: nobody
Component: Migrations Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Shadi Akiki)

I came across this case accidentally, and it's probably not a common use-case, but I'm reporting it anyway.
Also, it may as well be resolved in 2.0, but this was in 1.11.

The following query got generated from one of my migration files

INSERT INTO "appname_modelname" () SELECT  FROM "appname_modelname__old"

where I replaced my Application name with "appname" and model name with "modelname".

This query threw an error in sqlite3.

Here is the complete traceback

Traceback (most recent call last):
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 330, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: near ")": syntax error

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/migrations/migration.py", line 129, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 155, in database_forwards
    schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 256, in remove_field
    self._remake_table(model, delete_field=field)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 206, in _remake_table
    self.quote_name(model._meta.db_table),
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 120, in execute
    cursor.execute(sql, params)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/shadi/.local/share/virtualenvs/BSEC_CMS2/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 330, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: near ")": syntax error

Walking through the code, I think that in django/db/migrations/operations/fields.py in RemoveField.state_forwards, maybe something like the following is needed

# check if we're deleting the last field
if len(state.models[app_label, self.model_name_lower].fields) == 1:
    raise ValueError("Invalid operation to delete the last field")

<strike>Or maybe instead of generating a RemoveField, it should have been a RemoveModel</strike>

Edit: The migration file itself consisted of a RemoveField followed by a DeleteModel, so maybe it would have sufficed to generate a DeleteModel only

Change History (2)

comment:1 by Shadi Akiki, 6 years ago

Component: UncategorizedMigrations

comment:2 by Shadi Akiki, 6 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top