diff options
| author | Tobias Kunze <rixx@cutebit.de> | 2016-04-06 17:04:56 +0200 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-04-06 12:09:14 -0400 |
| commit | c643b4c9f2acfdcb562bdbec1d74ac797b890b9b (patch) | |
| tree | ade8a8d8e28cc76fd486d054520fb6fa5729791f | |
| parent | eed658d7c4dda695976c6845346b166960957eba (diff) | |
Refs #24016 -- Edited "Migrating data between third-party apps" howto.
| -rw-r--r-- | docs/howto/writing-migrations.txt | 74 |
1 files changed, 33 insertions, 41 deletions
diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt index 6ef6f6e74a..02c39dff40 100644 --- a/docs/howto/writing-migrations.txt +++ b/docs/howto/writing-migrations.txt @@ -272,63 +272,55 @@ 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 -============================================= +Migrating data between third-party apps +======================================= -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. +You can use a data migration to move data from one third-party application to +another. + +If you plan to remove the old app later, you'll need to set the ``dependencies`` +property based on whether or not the old app is installed. Otherwise, you'll +have missing dependencies once you uninstall the old app. Similarly, you'll +need to catch :exc:`LookupError` in the ``apps.get_model()`` call that +retrieves models from the old app. This approach allows you to deploy your +project anywhere without first installing and then uninstalling the old app. + +Here's a sample migration: .. snippet:: - :filename: myapp/migrations/0124_ensure_dependencies.py + :filename: myapp/migrations/0124_move_old_app_to_new_app.py from django.apps import apps as global_apps from django.db import migrations - def forward(apps, schema_editor): - """ - see below - """ + def forwards(apps, schema_editor): + try: + OldModel = apps.get_model('old_app', 'OldModel') + except LookupError: + # The old app isn't installed. + return + + NewModel = apps.get_model('new_app', 'NewModel') + NewModel.objects.bulk_create( + NewModel(new_attribute=old_object.old_attribute) + for old_object in OldModel.objects.all() + ) class Migration(migrations.Migration): - operations = [ - migrations.RunPython(forward, migrations.RunPython.noop), + migrations.RunPython(forwards, migrations.RunPython.noop), ] dependencies = [ ('myapp', '0123_the_previous_migration'), - ('new_external_app', '0001_initial'), + ('new_app', '0001_initial'), ] - if global_apps.is_installed('old_external_app'): - dependencies.append(('old_external_app', '0001_initial')) + if global_apps.is_installed('old_app'): + dependencies.append(('old_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 +Also consider what you want to happen when the migration is unapplied. You +could either do nothing (as in the example above) or remove some or all of the +data from the new application. Adjust the second argument of the :mod:`~django.db.migrations.operations.RunPython` operation accordingly. |
