我有一个使用两个数据库的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
答案 0 :(得分:0)
自Django 1.8以来问题解决了:https://docs.djangoproject.com/en/1.10/releases/1.8/#migrations
迁移操作RunPython和RunSQL现在调用数据库路由器的allow_migrate()方法。路由器可以使用新引入的app_label和提示参数来做出路由决策。要利用此功能,您需要将路由器更新为新的allow_migrate签名