有没有办法指定 Django 迁移中 RunPython 操作所关注的数据库别名?

Is there a way to specify the database alias that is concerned by a RunPython operation in a Django migration?

我有一个使用两个数据库的 Django 项目。我定义了一个 Database Router 并且在 运行 迁移时一切正常,除了 RunPython 迁移操作:在这种情况下我必须 "manually" 检查 RunPython代码是哪个数据库别名的代码函数 运行 决定是否应用给定的操作。

到目前为止,我已经实现了一个装饰器,我在每个 RunPython 代码函数上使用它来检查是否 运行 基于当前数据库别名的操作。它工作正常,但我想知道 Django 是否已经提供了一种方法来指定 RunPython 迁移所涉及的数据库别名,而无需自定义代码。有这样的方法吗?

有关信息,这是装饰器:

def run_for_db_aliases(database_aliases):
    def decorator(migration_function):
        def decorated(apps, schema_editor):
            if schema_editor.connection.alias not in database_aliases:
                return
            return migration_function(apps, schema_editor)
        return decorated
    return decorator

这允许我为 RunPython 迁移定义代码,如下所示:

@run_for_db_aliases(['default'])
def forwards_func(apps, schema_editor):
    # Perform data operations on models that are stored in the 'default' database
   ...

是否有更简洁的方法来执行此操作,例如实例化 RunPython 操作时的选项?

编辑:

这是我使用的模型和数据库路由器。

my_project/my_app/models.py

class A(models.Model):
    # The table for this model is in the 'default' database
    name = models.CharField(max_length=128)

class B(models.Model):
    # The table for this model is in the 'other' database
    description = models.CharField(max_length=128)

my_project/db_routers.py

class MyDBRouter(object):

    def _is_in_other(self, model):
        return model._meta.app_label == 'my_app' and model._meta.model_name == 'b'

    def db_for_read(self, model, **hints):
        return 'other' if self._is_in_other(model) else None

    def db_for_write(self, model, **hints):
        return 'other' if self._is_in_other(model) else None

    def allow_relation(self, obj1, obj2, **hints):
        # Pointless in this example
        return None

    def allow_migrate(self, db, model):
        if db == 'other':
            return self._is_in_other(model)
        if self._is_in_other(model):
            return False
        return None

自 Django 1.8 以来已解决的问题:https://docs.djangoproject.com/en/1.10/releases/1.8/#migrations

The migration operations RunPython and RunSQL now call the allow_migrate() method of database routers. The router can use the newly introduced app_label and hints arguments to make a routing decision. To take advantage of this feature you need to update the router to the new allow_migrate signature