#32263: squashmigrations produces incorrect result with a RenameModel on a
ForeignKey target.
-------------------------------------+-------------------------------------
     Reporter:  InvalidInterrupt     |                    Owner:  Anvesh
                                     |  Mishra
         Type:  Bug                  |                   Status:  assigned
    Component:  Migrations           |                  Version:  3.1
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Durval Carvalho):

 I tried to deal with this problem as follows. In the CreateModel.reduce
 function, when executed with a RenameModel operation, I check if the
 CreateModel operation has any fields that may have been impacted by the
 RenameModel operation, because in this scenario, these fields need to be
 updated for this renamed model.


 {{{

 def reduce(self, operation, app_label):
     ...
     elif impacted_fields := [
         (_, field)
         for _, field in self.fields
         if field.remote_field
         and field.remote_field.model ==
 f'{app_label}.{operation.old_name_lower}'
     ]:
         not_impacted_fields = [
             (_, field)
             for (_, field) in self.fields
             if (_, field) not in impacted_fields
         ]

         fixed_fields = []

         for (_, impacted_field) in impacted_fields:
             name, path, args, kwargs = impacted_field.deconstruct()
             kwargs['to'] = f'{app_label}.{operation.new_name_lower}'
             impacted_field = impacted_field.__class__(*args, **kwargs)
             fixed_fields.append((_, impacted_field))

         return [
             CreateModel(
                 self.name,
                 fields=not_impacted_fields + fixed_fields,
                 bases=self.bases,
                 managers=self.managers,
             ),
         ]
     ...
 }}}

 However, this approach did not work for the following reason. When the
 CreateModel operation is executed with its respective RenameModel, both
 are reduced to the new CreateModel operation. Then, some checks are made
 to decide whether this new resulting operation will be added to the list
 of new operations. But with this new reduction that I created, the other
 CreateModel operations, the ones that reference the renamed model, are
 also reduced, and this breaks the verification described below.

 {{{
 ...
         for i, operation in enumerate(operations):
             right = True  # Should we reduce on the right or on the left.
             # Compare it to each operation after it
             for j, other in enumerate(operations[i + 1 :]):
                 result = operation.reduce(other, app_label)
                 if isinstance(result, list):
                     in_between = operations[i + 1 : i + j + 1]
                     if right:
                         new_operations.extend(in_between)
                         new_operations.extend(result)
                     elif all(op.reduce(other, app_label) is True for op in
 in_between): # <<<<<<< This condition fails (I didn't understand what is
 being checked here)
                         # Perform a left reduction if all of the in-
 between
                         # operations can optimize through other.
                         new_operations.extend(result)
                         new_operations.extend(in_between)
                     else:
 # <<<<<<<< New operation `result` is not added to new operations list
                         # Otherwise keep trying.
                         new_operations.append(operation)
                         break
 ...
 }}}


 Now I am stuck, trying to think of a way to work around this problem.
 Do any of you have any suggestions?

-- 
Ticket URL: <https://code.djangoproject.com/ticket/32263#comment:14>
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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018715968041-0619c62c-bdda-4be2-9c9b-11f2fe328c16-000000%40eu-central-1.amazonses.com.

Reply via email to