'Django: Renaming Models, M2M Table not renamed
TLDR: Models moved to a new app. After migrating M2M relation refers to table that does not exist. Previous M2M table was not renamed.
Django Version: 3.2.3
Scenario:
I am refactoring a Django application. In this process I have moved some models to a new app. To do so, I renamed the tables as described by Haki Benita, using SeparateDatabaseAndState
.
One of the models Students
in the new app has a field with Many2Many relationship to another model Teachers
(which I also moved to the new app).
oldapp/migrations/000X_auto_XXX.py
operations = [
...
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.DeleteModel(
name='Students',
)
],
database_operations=[
migrations.AlterModelTable(
name='Students',
table='newapp_students'
)
]
),
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.DeleteModel(
name='Teachers',
)
],
database_operations=[
migrations.AlterModelTable(
name='Teachers',
table='newapp_Teachers'
)
]
),
...
]
newapp/migrations/0001_initial.py
operations = [
...
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.CreateModel(
name='Teacher',
fields=[...],
options={...},
)
],
database_operations=[]
),
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.CreateModel(
name='Students',
fields=[
...
('teachers', models.ManyToManyField(blank=True,related_name='students', to='newapp.Teachers')),
...
],
options={...},
)
],
database_operations=[]
),
...
]
After running python manage.py migrate
all the Models got renamed (so far so good)..
Problem: The automatically generated table for Many2Many was not renamed (oldapp_students_teachers
). However, the model in the new app refers to a table in the new app (newapp_students_teachers
) that does not exist.
I did some reasearch and it seems, that this problem was addresed and fixed several years ago 41b337efa085b6b9cfdb2cf724d977005ff77e75.
However for me the problem still remains. So what am I doing wrong?
Solution 1:[1]
I have similar problem while renaming User model, but I have fields in m2m tables which are not changed with migration. The only thing I could come up with is writing management command that will rename this fields. So I suppose you can do the same with something like this.
cursor.execute("ALTER TABLE oldapp_students_teachers RENAME TO newapp_students_teachers;" )
Solution 2:[2]
For me, the M2M tables were renamed correctly... unless they were defined with db_table
. Which makes sense, since otherwise Django can't assume that the names follow its conventions. In my case I could resolve this by adding AlterField
lines to remove db_table
from the M2M field definitions prior to the delete/rename operations.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Alexey Veretuk |
Solution 2 | jzskca |