Please consider the (contrived) minimal example below, part of an app
called `myapp`:
{{{
class Person(models.Model):
name = models.CharField(max_length=255)
children = 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
1. start a new project, start a new app called `myapp`, with models as
above.
2. run `makemigrations` and `migrate`
2. 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}}
]
}}}
4. rename the `Person` model to e.g. `Foo` and update all references in
code
5. run `makemigrations` and `migrate` 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.
--
Ticket URL: <https://code.djangoproject.com/ticket/34881>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.