summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrixx <rixx-git@cutebit.de>2016-04-03 17:20:35 +0200
committerTim Graham <timograham@gmail.com>2016-04-06 12:16:42 -0400
commit59ae2292df8daae365f989bdb388b4eb38d5927a (patch)
treef4101a7e930c71f3495ade4cf85b10fb76101280
parente043b85b1518c38f1d5fe5671ab0f4eccc569ce8 (diff)
[1.9.x] Fixed #24016 -- Added "Migrating data between third-party apps" howto.
Thanks to Markus, Marten and Sergei for help and review. Backport of b7ea494d65e4d9703a0a24f0cd708293df88f48b and c643b4c9f2acfdcb562bdbec1d74ac797b890b9b from master
-rw-r--r--AUTHORS1
-rw-r--r--docs/howto/writing-migrations.txt51
2 files changed, 52 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
index df9114a706..9975abf1d3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -700,6 +700,7 @@ answer newbie questions, and generally made Django that much better:
Tim Graham <timograham@gmail.com>
Tim Heap <tim@timheap.me>
Tim Saylor <tim.saylor@gmail.com>
+ Tobias Kunze <rixx@cutebit.de>
Tobias McNulty <http://www.caktusgroup.com/blog>
tobias@neuyork.de
Todd O'Bryan <toddobryan@mac.com>
diff --git a/docs/howto/writing-migrations.txt b/docs/howto/writing-migrations.txt
index 096b5e3b15..9950e3cefa 100644
--- a/docs/howto/writing-migrations.txt
+++ b/docs/howto/writing-migrations.txt
@@ -226,3 +226,54 @@ 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 between third-party apps
+=======================================
+
+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_move_old_app_to_new_app.py
+
+ from django.apps import apps as global_apps
+ from django.db import migrations
+
+ 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(forwards, migrations.RunPython.noop),
+ ]
+ dependencies = [
+ ('myapp', '0123_the_previous_migration'),
+ ('new_app', '0001_initial'),
+ ]
+
+ if global_apps.is_installed('old_app'):
+ dependencies.append(('old_app', '0001_initial'))
+
+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.