summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Kunze <rixx@cutebit.de>2016-04-06 17:04:56 +0200
committerTim Graham <timograham@gmail.com>2016-04-06 12:09:14 -0400
commitc643b4c9f2acfdcb562bdbec1d74ac797b890b9b (patch)
treeade8a8d8e28cc76fd486d054520fb6fa5729791f
parenteed658d7c4dda695976c6845346b166960957eba (diff)
Refs #24016 -- Edited "Migrating data between third-party apps" howto.
-rw-r--r--docs/howto/writing-migrations.txt74
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.