'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 Studentsin 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