2017-01-05 6 views
0

У меня есть проект Django, который использует две базы данных. Я определил Database Router, и все работает нормально при выполнении миграций, за исключением операций миграции RunPython: в этом случае мне нужно «вручную» проверить функцию кода RunPython, по которой выполняется псевдоним базы данных, чтобы решить, применять или не применять данный операции.Есть ли способ указать псевдоним базы данных, который связан с операцией RunPython в миграции Django?

До сих пор я реализовал декоратор, который я использую для каждой функции кода 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?

EDIT:

Вот модели и базы данных маршрутизатора я использую.

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

Если ваш маршрутизатор работает правильно, вам не нужен этот декоратор вообще – e4c5

+0

, вы можете отредактировать свой вопрос. вы не отправили ответ – e4c5

+0

Хорошо, что я плохо забыл упомянуть, что использовал Django 1.7 Похож, проблема была решена с версии 1.8: https://docs.djangoproject.com/en/1.10/releases/1.8/ #migrations – rparent

ответ

0

Проблема решена, поскольку Django 1.8: https://docs.djangoproject.com/en/1.10/releases/1.8/#migrations

миграцию операций RunPython и RunSQL в настоящее время вызовите метод allow_migrate() для маршрутизаторов баз данных. Маршрутизатор может использовать недавно введенные аргументы app_label и hints для принятия решения о маршрутизации. Чтобы воспользоваться этой функцией, вам необходимо обновить маршрутизатор до новой отметки allow_migrate