Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#24110 closed Bug (fixed)

Unapplying a migration has side-effects on the ProjectState passed to the method

Reported by: Markus Holtermann Owned by: Markus Holtermann
Component: Migrations Version: master
Severity: Release blocker Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Markus Holtermann)

django.db.migrations.migration.Migration.unapply() accepts an argument state that represents the project state right before the migration is applied. The current implementation alters this state when building the intermediate states to which each operation rolls back, instead of using a copy. This side effect results in errors where e.g. a model can exists in the state, but its gone from the database.

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/markus/Coding/django/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/home/markus/Coding/django/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/markus/Coding/django/django/core/management/base.py", line 390, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/markus/Coding/django/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/home/markus/Coding/django/django/core/management/commands/migrate.py", line 213, in handle
    executor.migrate(targets, plan, fake=options.get("fake", False))
  File "/home/markus/Coding/django/django/db/migrations/executor.py", line 73, in migrate
    state = self.unapply_migration(state, migration, fake=fake)
  File "/home/markus/Coding/django/django/db/migrations/executor.py", line 127, in unapply_migration
    state = migration.unapply(state, schema_editor)
  File "/home/markus/Coding/django/django/db/migrations/migration.py", line 135, in unapply
    operation.state_forwards(self.app_label, project_state)
  File "/home/markus/Coding/django/django/db/migrations/operations/models.py", line 53, in state_forwards
    list(self.managers),
  File "/home/markus/Coding/django/django/db/migrations/state.py", line 39, in add_model
    self.reload_model(app_label, model_name)
  File "/home/markus/Coding/django/django/db/migrations/state.py", line 61, in reload_model
    self._reload_one_model(rel_model._meta.app_label, rel_model._meta.model_name)
AttributeError: 'str' object has no attribute '_meta'

Change History (7)

comment:1 Changed 4 years ago by Markus Holtermann

It looks like not all _pending_lookups in the StateApps get resolved.

comment:2 Changed 4 years ago by Markus Holtermann

Description: modified (diff)
Summary: Related models in migration state are sometimes strings and not modelsUnapplying a migration has side-effects on the ProjectState passed to the method

comment:3 Changed 4 years ago by Markus Holtermann

Has patch: set
Needs documentation: set
Needs tests: set
Patch needs improvement: set

PR https://github.com/django/django/pull/3881

#24099 relies on a correct behavior of Migration.unapply()

comment:4 Changed 4 years ago by Claude Paroz

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Triage Stage: UnreviewedReady for checkin

comment:5 Changed 4 years ago by Markus Holtermann <info@…>

Resolution: fixed
Status: newclosed

In fdc2cc948725866212a9bcc97b9b7cf21bb49b90:

Fixed #24110 -- Rewrote migration unapply to preserve intermediate states

comment:6 Changed 4 years ago by Markus Holtermann <info@…>

In be158e36251df0b07556657da47cdaf10913c57a:

Refs #24110 -- Added a more descriptive release note and fixed a spelling mistake.

comment:7 Changed 4 years ago by Markus Holtermann <info@…>

In ef5889409bba675499dfd38831358daba16811ab:

[1.7.x] Fixed #24110 -- Rewrote migration unapply to preserve intermediate states

Backport of fdc2cc948725866212a9bcc97b9b7cf21bb49b90 and be158e36251df0b07556657da47cdaf10913c57a from master

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