diff options
| author | rixx <rixx-git@cutebit.de> | 2016-04-03 17:20:35 +0200 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2016-04-03 17:20:35 +0200 |
| commit | b7ea494d65e4d9703a0a24f0cd708293df88f48b (patch) | |
| tree | f36e2f1f47d9ec87b0d47a2cf187ac655c54132a /docs | |
| parent | b0803d64c4cd24c580a503cfe268e521128f45d7 (diff) | |
Fixed #24016 -- Added documentation about third-party app data migrations
There was confusion about how to migrate data from third-party
applications when you are going to uninstall the application later on.
Thanks to Markus, Marten and Sergei for help and review.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/howto/writing-migrations.txt | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt index adef507fa8..6ef6f6e74a 100644 --- a/docs/howto/writing-migrations.txt +++ b/docs/howto/writing-migrations.txt @@ -271,3 +271,64 @@ Prefer using ``dependencies`` over ``run_before`` when possible. You should only use ``run_before`` if it is undesirable or impractical to specify ``dependencies`` in the migration which you want to run after the one you are writing. + +Migrating data when replacing an external app +============================================= + +If you plan to move from one external application to another one with a similar +data structure, you can use a data migration. If you plan to remove the old +application later, you will need to set the ``dependencies`` property +dynamically. Otherwise you will have missing dependencies once you uninstall +the old application. + +.. snippet:: + :filename: myapp/migrations/0124_ensure_dependencies.py + + from django.apps import apps as global_apps + from django.db import migrations + + def forward(apps, schema_editor): + """ + see below + """ + + class Migration(migrations.Migration): + + operations = [ + migrations.RunPython(forward, migrations.RunPython.noop), + ] + dependencies = [ + ('myapp', '0123_the_previous_migration'), + ('new_external_app', '0001_initial'), + ] + + if global_apps.is_installed('old_external_app'): + dependencies.append(('old_external_app', '0001_initial')) + +In your data migration method, you will need to test for the old application +model: + +.. snippet:: + :filename: myapp/migrations/0124_ensure_dependencies.py + + def forward(apps, schema_editor): + try: + OldModel = apps.get_model('old_external', 'OldModel') + except LookupError: + return + + NewModel = apps.get_model('new_external', 'NewModel') + NewModel.objects.bulk_create( + NewModel(new_attribute=old_object.old_attribute) + for old_object in OldModel.objects.all() + ) + +This way you can deploy your application anywhere without first installing +and then uninstalling your old external dependency. If the old external +dependency is not installed when the migration runs it will just do nothing +instead of migrating the data. + +Please take also into consideration what you want to happen when the migration +is unapplied - you could either do nothing or remove some or all data from +the new application model; adjust the second argument of the +:mod:`~django.db.migrations.operations.RunPython` operation accordingly. |
