Opened 3 years ago

Closed 3 years ago

#32457 closed Bug (invalid)

SeparateDatabaseAndState fails with RemoveField

Reported by: Christian Bundy Owned by: nobody
Component: Migrations Version: 3.1
Severity: Normal Keywords: database state remove field
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 Christian Bundy)

Hi. We're doing multi-stage migrations with a blue-green deployment model, and currently bumping into an error. I think this is a small problem with a quick fix. The goal was to remove a field with three separate changes:

  1. Remove the field from the model and create a migration that removes the field from Django's state.
  2. Create a migration that removes the field from the database.

I've reproduced the error in a Git repository here, with the above migrations:

https://github.com/christianbundy/django-bug-remove-field/tree/main/example/migrations

Expected behavior: The migration succeeds.

Actual behavior:

  File "/usr/local/lib/python3.9/site-packages/django/db/migrations/operations/fields.py", line 158, in state_forwards
    old_field = model_state.fields.pop(self.name)
KeyError: 'last_name'

Relevant Django code: https://github.com/django/django/blob/d02d60eb0f032c9395199fb73c6cd29ee9bb2646/django/db/migrations/operations/fields.py#L162

Is there some other way that I should be making this change, or is this a bug in Django?

Thanks for the help!

Change History (4)

comment:1 by Christian Bundy, 3 years ago

Description: modified (diff)

comment:2 by Christian Bundy, 3 years ago

Description: modified (diff)

comment:3 by Christian Bundy, 3 years ago

Description: modified (diff)

comment:4 by Mariusz Felisiak, 3 years ago

Resolution: invalid
Status: newclosed

I'm not sure why you want to do this changes separately, but it's not a supported usage, see docs:

"A highly specialized operation that lets you mix and match the database (schema-changing) and state (autodetector-powering) aspects of operations. ... If the actual state of the database and Django’s view of the state get out of sync, this can break the migration framework, even leading to data loss."

In 0002_remove_person_last_name you removed Person.last_name field from the state so RemoveField() cannot work anymore. You can try to remove it manually in 0003_trigger_error with RunSQL().

For an example using SeparateDatabaseAndState, see Changing a ManyToManyField to use a through model.

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