Использование двух баз данных в Django (одна только для чтения) - PullRequest
0 голосов
/ 09 июля 2019

Я использую две базы данных, одну для чтения данных и затем записи данных в другую.Ниже приведен мой класс Router и мои изменения в настройках, но я очень плохо знаком с этой концепцией. Может ли кто-то с большим опытом в этой области подтвердить, что он должен работать или помогать вносить изменения?

Приложение называется «myapp»,база данных только для чтения, которую я назвал «readonly_db», и база данных, в которую я хочу записать, является базой данных «по умолчанию».

    class MyappRouter:
        def db_for_read(self, model, **hints):
            if model._meta.app_label == 'myapp':
                return 'readonly_db'
            return None
        def db_for_write(self, model, **hints):
            if model._meta.app_label == 'myapp'
                return 'default'
            return None

        def allow_relation(self, obj1, obj2, **hints):
            if obj1._meta.app_label == obj2._meta.app_label:
                return True
            else:
                return False
            return None

        def allow_migrate(self, db, **hints):
            if db == 'default':
                return True
            elif db == 'readonly_db':
                return False
            return None
    DATABASE_ROUTERS = ['<path to>.myapprouter.py']
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'myapp' ,
            'USER': 'USER',
            'PASSWORD': 'PASSWORD',
            'HOST': 'LOCALHOST',
            'PORT': '5432'
        }
        'readonly_db': {
            'ENGINE': 'django_postgres_readonly'
            'NAME': 'READONLY'
            'USER': 'USER'
            'PASSWORD': 'PASSWORD'
            'HOST': 'LOCALHOST'
            'PORT': '5432'
    }

1 Ответ

2 голосов
/ 09 июля 2019

Вы идете правильным путем.Я поделюсь решением, которое у меня сейчас работает.

settings.py

USE_REPLICA = eval_env_as_boolean("USE_REPLICA", False)

DATABASES = {
    "default": {
        "ENGINE": os.getenv("DB_ENGINE", "django.db.backends.sqlite3"),
        "NAME": os.getenv("DB_DATABASE", os.path.join(BASE_DIR, "db.sqlite3")),
        "USER": os.getenv("DB_USER"),
        "HOST": os.getenv("DB_HOST"),
        "PORT": os.getenv("DB_PORT"),
        "PASSWORD": os.getenv("DB_PASSWORD"),
    }
}

DATABASES["default"]["CONN_MAX_AGE"] = int(os.getenv("DB_CONN_MAX_AGE", 0))  # type: ignore

if USE_REPLICA:
    DATABASES["replica"] = {
        "ENGINE": os.getenv("DB_ENGINE_REPLICA"),
        "NAME": os.getenv("DB_DATABASE_REPLICA"),
        "USER": os.getenv("DB_USER_REPLICA"),
        "HOST": os.getenv("DB_HOST_REPLICA"),
        "PORT": os.getenv("DB_PORT_REPLICA"),
        "PASSWORD": os.getenv("DB_PASSWORD_REPLICA"),
    }

    DATABASES["replica"]["CONN_MAX_AGE"] = int(os.getenv("DEFAULT_DB_CONN_MAX_AGE_REPLICA", 0))  # type: ignore
    DATABASE_ROUTERS = ["my_app.setup.db_routing.DatabaseRouter"]

db_routing.py

class DatabaseRouter:
    """
    A router to control all database operations on models in the
    auth application.
    """

    def db_for_read(self, model, **hints):
        """
        Always read from REPLICA database
        """
        return "replica"

    def db_for_write(self, model, **hints):
        """
        Always write to DEFAULT database
        """
        return "default"

    def allow_relation(self, obj1, obj2, **hints):
        """
        Objects from REPLICA and DEFAULT are de same, then True always
        """
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Only DEFAULT database
        """
        return db == "default"

По сути, вы можете немного упростить свой маршрутизатор

ОБНОВЛЕНИЕ:

USE_REPLICA существует только как опция, поэтому я могу быстро отключить базу данных чтения.Settings.py запускается только при запуске системы, поэтому конфигурация реплики добавляется при запуске системы, но только если эта переменная существует.

О CONN_MAX_AGE вы можете увидеть больше здесь здесь тоже в контрольном списке для производства.

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