Opened 14 months ago
Last modified 5 months ago
#34881 closed Bug
Model-rename migration fails with IntegrityError if m2m relations to self exist — at Version 6
Reported by: | dennisvang | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | dev |
Severity: | Normal | Keywords: | sqlite |
Cc: | Simon Charette, Mariusz Felisiak, David Wobrock, Jase Hackman | 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 )
Description
Please consider the (contrived) minimal example below, part of an app called myapp
:
class Person(models.Model): name = models.CharField(max_length=255) relatives = models.ManyToManyField( to='self', through='myapp.Relation', blank=True ) class Relation(models.Model): parent = models.ForeignKey( to='myapp.Person', related_name='relations_as_parent', on_delete=models.CASCADE, ) child = models.ForeignKey( to='myapp.Person', related_name='relations_as_child', on_delete=models.CASCADE, )
Now suppose I rename the Person
model to Foo
and update corresponding references.
Then I run manage.py makemigrations
, which correctly recognizes that the model has been renamed.
Now, applying this migration to an empty database works, without issue, but applying the migration to a database with existing data fails with an IntegrityError
.
Steps to reproduce
- start a new project, start a new app called
myapp
, with models as above. - run
makemigrations
andmigrate
- Load (valid) data from the following fixture:
[ {"model": "myapp.person", "pk": 1, "fields": {"name": "Jenny"}}, {"model": "myapp.person", "pk": 2, "fields": {"name": "Johnny"}}, {"model": "myapp.person", "pk": 3, "fields": {"name": "Mom"}}, {"model": "myapp.person", "pk": 4, "fields": {"name": "Dad"}}, {"model": "myapp.relation", "pk": 1, "fields": {"parent": 3, "child": 1}}, {"model": "myapp.relation", "pk": 2, "fields": {"parent": 3, "child": 2}}, {"model": "myapp.relation", "pk": 3, "fields": {"parent": 4, "child": 1}}, {"model": "myapp.relation", "pk": 4, "fields": {"parent": 4, "child": 2}} ]
- rename the
Person
model to e.g.Foo
and update all references in code - run
makemigrations
andmigrate
again
What happens
The migrate
command fails with
django.db.utils.IntegrityError: The row in table 'myapp_relation' with primary key '1' has an invalid foreign key: myapp_relation.child_id contains a value '1' that does not have a corresponding value in myapp_person.id.
But a Person
with id=1
does exist in the database.
What I would expect to happen
I would expect this to work without any problems.
Notes
I also tried the same steps with an implicit through
model , i.e. children = models.ManyToManyField(to='self', blank=True)
.
This works without issue.
Change History (6)
comment:1 by , 14 months ago
Summary: | Migration fails with IntegrityError after renaming model with existing m2m relations to self → Migration fails with IntegrityError after renaming model if m2m relations to self exist |
---|
comment:2 by , 14 months ago
Summary: | Migration fails with IntegrityError after renaming model if m2m relations to self exist → Model rename fails during migration if m2m relations to self exist |
---|
comment:3 by , 14 months ago
Summary: | Model rename fails during migration if m2m relations to self exist → Model-rename migration fails with IntegrityError if m2m relations to self exist |
---|
comment:4 by , 14 months ago
Description: | modified (diff) |
---|
comment:5 by , 14 months ago
Description: | modified (diff) |
---|
comment:6 by , 14 months ago
Description: | modified (diff) |
---|