Opened 9 years ago
Closed 6 years ago
#26180 closed Bug (duplicate)
Altering unique_together still sometimes missing deleted fields
Reported by: | Julian Andrews | Owned by: | Akshesh Doshi |
---|---|---|---|
Component: | Migrations | Version: | 1.9 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | yes |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
This is likely a missed edge case from #23614.
Steps to reproduce:
- Create an app
spam
- Create a model
Spam
class Spam(models.Model): a = models.CharField(max_length=255) b = models.CharField(max_length=255) c = models.CharField(max_length=255) class Meta: unique_together = ( ('a', 'b'), ('b', 'c'), )
- Make migrations
- Delete field
Spam.c
- Delete the second
unique_together
constraint (('b', 'c')
) - Make migrations
- Run migrations
Output:
django.core.exceptions.FieldDoesNotExist: Spam has no field named u'c'
Note that the bug doesn't occur if no unique togther
constraints remain.
Manually reversing the order of the operations in the migration (to remove the index first) produces a functional migration.
Attachments (1)
Change History (10)
comment:1 by , 9 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Type: | Uncategorized → Bug |
by , 8 years ago
Attachment: | ticket26180-temp-fix.diff added |
---|
comment:3 by , 8 years ago
The patch temporarily fixes the issue (attaching for anyone who gets stuck due to this bug) but some other edge cases would still get left. The actual fix would involve some changes in migrations.optimizer
or the reduce
methods of AlterUniqueTogether
or RemoveField
operations AFAICS.
comment:4 by , 8 years ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:5 by , 8 years ago
Has patch: | unset |
---|
Unchecking "Has patch" due to "not the right approach" comment on the PR.
comment:6 by , 8 years ago
Has patch: | set |
---|---|
Needs documentation: | set |
Needs tests: | set |
An initial implementation of the suggested approach - https://github.com/django/django/pull/7038
comment:8 by , 7 years ago
This issue just bit me on django 1.11.4, and required a couple hours of debugging to sort out.
comment:9 by , 6 years ago
Resolution: | → duplicate |
---|---|
Status: | assigned → closed |
Pretty sure this is a duplicate of #28862 as well. I'll close this one as since the other one has more context.
This is happening because the
RemoveField
operation is called before calling theAlterUniqueTogether
operation, resulting in the dropping of the field before the index.In the
autodetector.py
, although theRemoveField
operations are created before theAlterUniqueTogether
operations but the `_sort_migrations` method corrects the order of these operations to bringAlterUniqueTogether
beforeRemoveField
. But the `_optimize_migrations` method again reverses this order inself.migrations
(which is finally what is returned by the_detect_changes
method) with no optimization as such.This change is somewhat related to https://github.com/django/django/commit/e470f311d654267ec86f9a6325ec500345b9dff2