[Django] #34881: Migration fails with IntegrityError after renaming model with existing m2m relations to self

3 views
Skip to first unread message

Django

unread,
Sep 28, 2023, 11:05:28 AM9/28/23
to django-...@googlegroups.com
#34881: Migration fails with IntegrityError after renaming model with existing m2m
relations to self
-----------------------------------------+------------------------
Reporter: dennisvang | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
== Description

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.

Reply all
Reply to author
Forward
0 new messages