Opened 10 years ago

Last modified 10 years ago

#23733 closed Bug

Following #23556: manage multi-apps dependencies when squashing — at Version 3

Reported by: Stephane "Twidi" Angel Owned by: nobody
Component: Migrations Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Stephane "Twidi" Angel)

Following ticket #23556 and PR #3280, I found a problem with squashing on different apps, each one depending on the other at different step

app1:

  • 1_auto
  • 2_auto
  • 3_auto, with dependency on ('app2', '2_auto')
  • 4_auto

With this squash:

  • 2_squashed_3 (squash of 2_auto and 3_auto)

And app2:

  • 1_auto, with dependency on ('app1', '1_auto')
  • 2_auto

With this squash:

  • 1_squashed_2 (squash of 1_auto and 2_auto)

With this configuration, there is an error in build_graph:

File "django/db/migrations/loader.py", line 224, in build_graph
    normal[child_key].dependencies.remove(replaced)
KeyError: ('app1', '3_auto')

The reason is simple, ('app1', '3_auto') where replaced by ('app1', '2_squashed_3')

So I came up with this patch:

  • django/db/migrations/loader.py

    diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py
    index 9f8be33..0ee3794 100644
    a b class MigrationLoader(object):  
    219219                for child_key in reverse_dependencies.get(replaced, set()):
    220220                    if child_key in migration.replaces:
    221221                        continue
    222                     normal[child_key].dependencies.remove(replaced)
    223                     normal[child_key].dependencies.append(key)
     222                    # child_key may appear in a replacement
     223                    if child_key in reverse_replacements:
     224                        for replaced_child_key in reverse_replacements[child_key]:
     225                            if replaced in replacing[replaced_child_key].dependencies:
     226                                replacing[replaced_child_key].dependencies.remove(replaced)
     227                                replacing[replaced_child_key].dependencies.append(key)
     228                    else:
     229                        normal[child_key].dependencies.remove(replaced)
     230                        normal[child_key].dependencies.append(key)
    224231            normal[key] = migration
    225232            # Mark the replacement as applied if all its replaced ones are
    226233            if all(applied_statuses):

Note that I loop on reverse_replacements[child_key], but I'm not sure how we can have many entries here

I'll provide a PR with two commits:

  • one with a test showing the failure
  • one with the patch

Change History (3)

comment:1 by Stephane "Twidi" Angel, 10 years ago

comment:2 by Stephane "Twidi" Angel, 10 years ago

Description: modified (diff)

comment:3 by Stephane "Twidi" Angel, 10 years ago

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