Джанго - как указать базу данных для модели? - PullRequest
23 голосов
/ 19 августа 2010

Есть ли способ указать, что модель (или даже приложение) должна когда-либо использовать только одну конкретную базу данных?

Я работаю с устаревшей базой данных, которую не хочу менять. У меня есть две базы данных - по умолчанию это sqlite, который можно использовать для администрирования и т. Д., И устаревшая. Я использовал inspectdb для создания модели (части) устаревшей базы данных, и она имеет managed = False. Но есть ли способ указать в самой модели, что она применяется только к конкретной базе данных?

Я вижу, что вы можете указать using=databasename в некоторых наборах запросов и т. Д., Но это плохо для таких вещей, как Databrowse (и, возможно, также для общих представлений?). Недостатком Databrowse может быть то, что вы не можете указать базу данных, но кажется, что это правильное место для указания именно модели ...

Тогда я подумал, что, возможно, ответ - написать собственный менеджер моделей , который ссылается только на мою устаревшую базу данных - но в документах ничего подобного не упоминается.

У меня просто другая ментальная модель того, как можно использовать несколько баз данных для мира Django?

Ответы [ 3 ]

14 голосов
/ 20 декабря 2017

Нельзя указать базу данных для модели, но вы можете определить ее в пользовательском классе маршрутизатора БД.

# app/models.py
class SomeModel(models.Model):
    ...

# app/dbrouters.py
from app.models import SomeModel
...
class MyDBRouter(object):

    def db_for_read(self, model, **hints):
        """ reading SomeModel from otherdb """
        if model == SomeModel:
            return 'otherdb'
        return None

    def db_for_write(self, model, **hints):
        """ writing SomeModel to otherdb """
        if model == SomeModel:
            return 'otherdb'
        return None


# app/settings.py
DATABASE_ROUTERS = ('app.dbrouters.MyDBRouter',)
...
DATABASES = {
    ...
    'otherdb': {
        ....
    }
}
12 голосов
/ 19 августа 2010

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

https://docs.djangoproject.com/en/1.8/topics/db/multi-db/

0 голосов
/ 19 апреля 2019

Я обнаружил, что вы можете довольно просто направлять модели с помощью этого менеджера:

class SecondDbManager(models.Manager):
    def get_queryset(self):
        qs = super().get_queryset()

        # if `use_db` is set on model use that for choosing the DB
        if hasattr(self.model, 'use_db'):
            qs = qs.using(self.model.use_db)

        return qs

Просто добавьте use_db='databasename' и этот менеджер к вашей модели, и он работает.

Или, чтобы еще больше упростить его, я создал для него базовую модель:

class SecondDbBase(models.Model):
    use_db = 'my_second_db'

    objects = SecureDbManager()

    class Meta:
        abstract = True

И с этим все, что вам нужно сделать, это расширить его так. Вместо:

class Customer(models.Model):

Просто сделайте это, и это сработает:

class Customer(SecondDbBase):

PS. Я не уверен, является ли это хорошей практикой или лучшим решением, но оно работает, и маршрутизация к другим базам данных очень проста:)

PSS. Я когда-либо использовал их только для чтения и записи таблиц, которые не управляются Django (managed = False), поэтому, если вам нужно создать миграции для них, я не уверен, работает ли это или нет. Возможно, для этого еще нужно использовать DATABASE_ROUTERS.

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