在 Django 中使用两个数据库(一个只读)
Using Two Databases in Django (one read-only)
我正在使用两个数据库,一个从另一个数据库读取数据,然后将数据写入另一个数据库。下面是我的路由器 class 和我对设置的更改,但我对这个概念很陌生,在这方面有更多经验的人可以确认它应该工作或帮助进行编辑吗?
应用程序命名为"myapp",只读数据库我命名为"readonly_db",我要写入的数据库是"default"数据库
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'
}
你走对了。我将分享我目前 运行.
的解决方案
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
仅在系统启动时运行,因此在系统启动时添加副本配置,但前提是该变量存在。
我正在使用两个数据库,一个从另一个数据库读取数据,然后将数据写入另一个数据库。下面是我的路由器 class 和我对设置的更改,但我对这个概念很陌生,在这方面有更多经验的人可以确认它应该工作或帮助进行编辑吗?
应用程序命名为"myapp",只读数据库我命名为"readonly_db",我要写入的数据库是"default"数据库
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'
}
你走对了。我将分享我目前 运行.
的解决方案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
仅在系统启动时运行,因此在系统启动时添加副本配置,但前提是该变量存在。