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

时间:2017-01-05 12:31:43

标签: django django-migrations django-1.7

我有一个使用两个数据库的Django项目。我定义了一个Database Router,在运行迁移时一切正常,但RunPython迁移操作除外:在这​​种情况下,我必须手动"检查代码运行的数据库别名的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

1 个答案:

答案 0 :(得分:0)

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

  

迁移操作RunPython和RunSQL现在调用数据库路由器的allow_migrate()方法。路由器可以使用新引入的app_label和提示参数来做出路由决策。要利用此功能,您需要将路由器更新为新的allow_migrate签名