#24110: Unapplying a migration has side-effects on the ProjectState passed to 
the
method
---------------------------------+--------------------------------------
     Reporter:  MarkusH          |                    Owner:  MarkusH
         Type:  Bug              |                   Status:  new
    Component:  Migrations       |                  Version:  master
     Severity:  Release blocker  |               Resolution:
     Keywords:                   |             Triage Stage:  Unreviewed
    Has patch:  0                |      Needs documentation:  0
  Needs tests:  0                |  Patch needs improvement:  0
Easy pickings:  0                |                    UI/UX:  0
---------------------------------+--------------------------------------
Description changed by MarkusH:

Old description:

> In some edge cases, I think, related models in the migration state are
> referenced via strings rather than `__fake__` models. This is related to
> #23745 and 1aa3e09c2043c88a760e8b73fb95dc8f1ffef50e
>
> {{{#!python
> 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'
> }}}
>
> I've yet to figure out when this is happening exactly.

New description:

 `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.

 {{{#!python
 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'
 }}}

--

--
Ticket URL: <https://code.djangoproject.com/ticket/24110#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.f45d56ba9549677b7b99f4c4bf22f5d4%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to