【问题标题】:Using Two Databases in Django (one read-only)在 Django 中使用两个数据库(一个是只读的)
【发布时间】:2019-07-09 14:25:42
【问题描述】:

我正在使用两个数据库,一个从另一个数据库读取数据,然后将数据写入另一个数据库。下面是我的路由器类和我对设置的更改,但对这个概念非常陌生,在这方面有更多经验的人可以确认它应该可以工作或帮助进行编辑吗?

应用程序名为“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'
    }

【问题讨论】:

    标签: python django database multiple-databases


    【解决方案1】:

    你走对了。我将分享我目前正在运行的解决方案。

    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你可以看到更多herehere 也在生产清单上。

    【讨论】:

    • 您能再解释一下 USE_REPLICA 吗?我很困惑为什么在最初创建它时不将它放在 DATABASES 字典中。 ["CONN_MAX_AGE"] 也有点失落。
    • 如果我在写之前对只读数据库中的数据进行操作,我会不会把allow_relation改成return False
    • @Kyle。我很难快速解释这一点,但这是一个很好的解释,这就是我明白我对它的了解有多么少的地方。 stackoverflow.com/a/35410784/3517631
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    • 2022-07-05
    • 2016-03-17
    • 1970-01-01
    • 2022-04-06
    相关资源
    最近更新 更多