Loading docs/topics/migrations.txt +16 −53 Original line number Diff line number Diff line Loading @@ -435,68 +435,31 @@ You can pass a second callable to want executed when migrating backwards. If this callable is omitted, migrating backwards will raise an exception. .. _data-migrations-and-multiple-databases: Accessing models from other apps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data migrations and multiple databases ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When writing a ``RunPython`` function that uses models from apps other than the one in which the migration is located, the migration's ``dependencies`` attribute should include the latest migration of each app that is involved, otherwise you may get an error similar to: ``LookupError: No installed app with label 'myappname'`` when you try to retrieve the model in the ``RunPython`` function using ``apps.get_model()``. When using multiple databases, you may need to figure out whether or not to run a migration against a particular database. For example, you may want to **only** run a migration on a particular database. In order to do that you can check the database connection's alias inside a ``RunPython`` operation by looking at the ``schema_editor.connection.alias`` attribute:: from django.db import migrations def forwards(apps, schema_editor): if not schema_editor.connection.alias == 'default': return # Your migration code goes here class Migration(migrations.Migration): dependencies = [ # Dependencies to other migrations ] operations = [ migrations.RunPython(forwards), ] You can also use your database router's ``allow_migrate()`` method, but keep in mind that the imported router needs to stay around as long as it is referenced inside a migration: .. snippet:: :filename: myapp/dbrouters.py class MyRouter(object): def allow_migrate(self, db, model): return db == 'default' Then, to leverage this in your migrations, do the following:: from django.db import migrations from myappname.dbrouters import MyRouter def forwards(apps, schema_editor): MyModel = apps.get_model("myappname", "MyModel") if not MyRouter().allow_migrate(schema_editor.connection.alias, MyModel): return # Your migration code goes here In the following example, we have a migration in ``app1`` which needs to use models in ``app2``. We aren't concerned with the details of ``move_m1`` other than the fact it will need to access models from both apps. Therefore we've added a dependency that specifies the last migration of ``app2``:: class Migration(migrations.Migration): dependencies = [ # Dependencies to other migrations ('app1', '0001_initial'), # added dependency to enable using models from app2 in move_m1 ('app2', '0004_foobar'), ] operations = [ migrations.RunPython(forwards), migrations.RunPython(move_m1), ] More advanced migrations Loading Loading
docs/topics/migrations.txt +16 −53 Original line number Diff line number Diff line Loading @@ -435,68 +435,31 @@ You can pass a second callable to want executed when migrating backwards. If this callable is omitted, migrating backwards will raise an exception. .. _data-migrations-and-multiple-databases: Accessing models from other apps ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Data migrations and multiple databases ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When writing a ``RunPython`` function that uses models from apps other than the one in which the migration is located, the migration's ``dependencies`` attribute should include the latest migration of each app that is involved, otherwise you may get an error similar to: ``LookupError: No installed app with label 'myappname'`` when you try to retrieve the model in the ``RunPython`` function using ``apps.get_model()``. When using multiple databases, you may need to figure out whether or not to run a migration against a particular database. For example, you may want to **only** run a migration on a particular database. In order to do that you can check the database connection's alias inside a ``RunPython`` operation by looking at the ``schema_editor.connection.alias`` attribute:: from django.db import migrations def forwards(apps, schema_editor): if not schema_editor.connection.alias == 'default': return # Your migration code goes here class Migration(migrations.Migration): dependencies = [ # Dependencies to other migrations ] operations = [ migrations.RunPython(forwards), ] You can also use your database router's ``allow_migrate()`` method, but keep in mind that the imported router needs to stay around as long as it is referenced inside a migration: .. snippet:: :filename: myapp/dbrouters.py class MyRouter(object): def allow_migrate(self, db, model): return db == 'default' Then, to leverage this in your migrations, do the following:: from django.db import migrations from myappname.dbrouters import MyRouter def forwards(apps, schema_editor): MyModel = apps.get_model("myappname", "MyModel") if not MyRouter().allow_migrate(schema_editor.connection.alias, MyModel): return # Your migration code goes here In the following example, we have a migration in ``app1`` which needs to use models in ``app2``. We aren't concerned with the details of ``move_m1`` other than the fact it will need to access models from both apps. Therefore we've added a dependency that specifies the last migration of ``app2``:: class Migration(migrations.Migration): dependencies = [ # Dependencies to other migrations ('app1', '0001_initial'), # added dependency to enable using models from app2 in move_m1 ('app2', '0004_foobar'), ] operations = [ migrations.RunPython(forwards), migrations.RunPython(move_m1), ] More advanced migrations Loading