mirror of https://github.com/django/django.git
Refs #24016 -- Edited "Migrating data between third-party apps" howto.
This commit is contained in:
parent
eed658d7c4
commit
c643b4c9f2
|
@ -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
|
``dependencies`` in the migration which you want to run after the one you are
|
||||||
writing.
|
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
|
You can use a data migration to move data from one third-party application to
|
||||||
data structure, you can use a data migration. If you plan to remove the old
|
another.
|
||||||
application later, you will need to set the ``dependencies`` property
|
|
||||||
dynamically. Otherwise you will have missing dependencies once you uninstall
|
If you plan to remove the old app later, you'll need to set the ``dependencies``
|
||||||
the old application.
|
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::
|
.. 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.apps import apps as global_apps
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
def forward(apps, schema_editor):
|
def forwards(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:
|
try:
|
||||||
OldModel = apps.get_model('old_external', 'OldModel')
|
OldModel = apps.get_model('old_app', 'OldModel')
|
||||||
except LookupError:
|
except LookupError:
|
||||||
|
# The old app isn't installed.
|
||||||
return
|
return
|
||||||
|
|
||||||
NewModel = apps.get_model('new_external', 'NewModel')
|
NewModel = apps.get_model('new_app', 'NewModel')
|
||||||
NewModel.objects.bulk_create(
|
NewModel.objects.bulk_create(
|
||||||
NewModel(new_attribute=old_object.old_attribute)
|
NewModel(new_attribute=old_object.old_attribute)
|
||||||
for old_object in OldModel.objects.all()
|
for old_object in OldModel.objects.all()
|
||||||
)
|
)
|
||||||
|
|
||||||
This way you can deploy your application anywhere without first installing
|
class Migration(migrations.Migration):
|
||||||
and then uninstalling your old external dependency. If the old external
|
operations = [
|
||||||
dependency is not installed when the migration runs it will just do nothing
|
migrations.RunPython(forwards, migrations.RunPython.noop),
|
||||||
instead of migrating the data.
|
]
|
||||||
|
dependencies = [
|
||||||
|
('myapp', '0123_the_previous_migration'),
|
||||||
|
('new_app', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
Please take also into consideration what you want to happen when the migration
|
if global_apps.is_installed('old_app'):
|
||||||
is unapplied - you could either do nothing or remove some or all data from
|
dependencies.append(('old_app', '0001_initial'))
|
||||||
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.
|
:mod:`~django.db.migrations.operations.RunPython` operation accordingly.
|
||||||
|
|
Loading…
Reference in New Issue