Opened 3 years ago

Last modified 10 months ago

#24686 new New feature

Support for Moving a model between two Django apps

Reported by: Alex Rothberg Owned by: nobody
Component: Migrations Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: yes
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

An issue that I run into is that at some point one of my apps becomes so large that I decide to split the application into a number of separate logical units. Right now the Django migration system leaves me on my own to write a correct migration to support updating the db to reflect the new multi-app layout.

There is an SO post that attempts to outline a solution but I would suggest trying to detect these model moves and then auto-generating these migrations.

Change History (9)

comment:1 Changed 3 years ago by Tim Graham

Component: UncategorizedMigrations
Needs documentation: set
Triage Stage: UnreviewedAccepted
Version: 1.8master

Not sure about feasibility of detecting/auto-generating, but if not, we could certainly document the SeparateDatabaseAndState solution in docs/howto/writing-migrations.txt.

comment:2 Changed 3 years ago by Alex Rothberg

I'm not sure how the plumbing works for migrations, but I would think the auto-detect logic would work like renaming of fields where if a model with the same name is deleted in one app and created in another the user is prompted with "did you move this model...".

comment:3 Changed 3 years ago by Marten Kenbeek

An actual implementation would supersede #24016.

I don't think the operation to move a model to another app has to be significantly more complex that the current RenameModel. The autodetection, on first sight, is just a matter of removing this check: https://github.com/django/django/blob/master/django/db/migrations/autodetector.py#L421

I do have some concerns about dependencies. If the migration lives in the old app, the autodetector won't be able to detect that the next migration in the new app depends on the RenameModel migration in the old app. Likewise, if the migration lives in the new app, the next migration in the old app won't have a dependency on the migration that moves the model. The last case might not be a problem, but I can't say that off the top of my head.

comment:4 Changed 3 years ago by Alex Rothberg

Crazy question, but what about project level migrations?

comment:5 in reply to:  4 Changed 3 years ago by Markus Holtermann

Referring back to the example solution from SO:

As soon as you remove the old_app from installed apps and apply the migrations on an empty database the SeparateDatabaseAndState operation in new_app will only create the model in memory but no database table. Therefore it's not an option to migrate data between apps to get rid of one app it this simple form.

Replying to cancan101:

Crazy question, but what about project level migrations?

What about them? You can define settings.MIGRATION_MODULES and put all app migrations in your project. But I advice you to not do that unless there is a 3rd party app that doesn't have Django migration support. Then this is the way to go to add migrations for that particular app.

Replying to knbk:

I do have some concerns about dependencies. If the migration lives in the old app, the autodetector won't be able to detect that the next migration in the new app depends on the RenameModel migration in the old app. Likewise, if the migration lives in the new app, the next migration in the old app won't have a dependency on the migration that moves the model. The last case might not be a problem, but I can't say that off the top of my head.

Sounds about right to me. You will eventually run into a hellhole of dependencies.

comment:6 Changed 3 years ago by Alex Rothberg

@MarkusH Are you saying that the solution posted on SO won't work?
I was suggesting the project level migrations to address the issues raised by @knbk so that the migrator could see both apps.

comment:7 Changed 3 years ago by Markus Holtermann

@cancan101, I'm saying that you will have trouble to get the suggested migrations work on an empty database once old_app is removed from the list of installed apps. To be specific, since you already need to fix the migration dependencies it's probably not that big of a deal to also drop the SeparateDatabaseAndState and replace it with a CreateModel operation.

comment:8 Changed 12 months ago by Florian Klink

I also ran into this today, when pulling some models into a separate app.

The stackoverflow post does not work anymore as soon as there are cross-app foreign keys, but this example here does.
In the solution outlined there, a migration inside the new app depends on a migration of the old app (see here), so loading all migrations should at least break as soon if you remove the old app from INSTALLED_APPS ;-)

Given the currently needed amount of manual work, we should really try to detect these movements and produce migrations like above.

comment:9 Changed 10 months ago by Petr Dlouhý

Maybe this could be separated into two separate tasks.
We could first create database operation like django.db.models.MoveToApp. This alone could save a lot of manual work and confusion for developers.

Second stage would be creating the autodetection mechanism, which would make migrations with this operation automatically.

Note: See TracTickets for help on using tickets.
Back to Top