Экземпляр модели Django getattr в ландшафте нескольких баз данных - PullRequest
0 голосов
/ 17 января 2019

У меня несколько баз данных с "default": {} в базах данных. Я не нуждаюсь в БД по умолчанию и сделал это для согласованности, как предложено в django docs.

Настройки базы данных установлены следующим образом:

DATABASES = {
    'default': {},
    'mydb': {
        'ENGINE': 'django.db.backends.mysql', 
        ...
    },
    'mydb2': {
        'ENGINE': 'django.db.backends.mysql', 
        ...
        }
    }

У меня также есть некоторые Model1, которые связывают Model2 с FK, например:

class Model1(models.Model):
    name = models.CharField(max_length=50)
    related_field = models.ForeignKey( 
        "Model2",
        db_index=True, 
        null=True, blank=True,
        on_delete=models.SET_NULL)

class Model2(models.Model):
    name = models.CharField(max_length=50)

Теперь я борюсь со странным поведением: имея экземпляр Model1 в одной из баз данных, я хочу получить связанный с ним экземпляр из Model2, я использую:

inst1 = Model1.objects.using("mydb").get(...) # this sets inst1._state.db to "mydb
related = getattr(inst1, "related_field")

и получите ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

Таким образом, вместо соблюдения inst1._state.db лежащего в основе ForwardManyToOneDescriptor (). __get__ метода inits manager с базой данных по умолчанию, что приводит к этому исключению.

Мой уродливый обходной путь, пытающийся сделать обобщенную функцию для этого:

from django.apps import apps

related_model = apps.get_model(inst1._meta.app_label, inst1._meta.model_name)
related_object = related_model.objects.using(inst1._state.db).get(...)

Есть ли способ заставить getattr (instance, relatedFK) обратить внимание на instance._state_db?

1 Ответ

0 голосов
/ 17 января 2019

Параметр DATABASES должен настраивать базу данных по умолчанию ; Также может быть указано любое количество дополнительных баз данных.

Мы должны предоставить базу данных по умолчанию, чтобы вы могли сделать что-то вроде этого:

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    ...
  },
  'mydb': {
    'ENGINE': 'django.db.backends.mysql',
    ...
  },
  'mydb2': {
    'ENGINE': 'django.db.backends.mysql',
    ...
  }
}

Ссылка: https://docs.djangoproject.com/en/2.0/ref/settings/#databases

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...