Files
Django/gvsdsdk/db_router.py

94 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""gvsdsdk.db_router — 开箱即用的 SAAS 数据库路由器
子服务器只需在 settings.py 中配置:
DATABASE_ROUTERS = ['gvsdsdk.db_router.SAASDatabaseRouter']
即可自动将 gvsdsdk 的所有模型路由到 SAAS 主库。
配置项settings.py
GVSDSDK_SAAS_DB_ALIAS = 'saas' # SAAS 数据库别名,默认 'saas'
GVSDSDK_SAAS_READ_ONLY = True # 子服务器是否只读,默认 True
"""
class SAASDatabaseRouter:
"""SAAS 模型数据库路由器——将 gvsdsdk 模型路由到 SAAS 主库
用法:
# settings.py
DATABASES = {
'default': { ... }, # 本地数据库
'saas': { # SAAS 主库
'ENGINE': 'django.db.backends.mysql',
'NAME': 'Users',
...
},
}
DATABASE_ROUTERS = ['gvsdsdk.db_router.SAASDatabaseRouter']
# 可选配置
GVSDSDK_SAAS_DB_ALIAS = 'saas' # 默认 'saas'
GVSDSDK_SAAS_READ_ONLY = True # 默认 True子服务器只读
"""
# gvsdsdk 内所有模块前缀
_GVSDSDK_MODULES = frozenset({
'gvsdsdk.models',
'gvsdsdk.commission.models',
'gvsdsdk.payment.models',
})
# gvsdsdk 内所有 app_label
_GVSDSDK_APP_LABELS = frozenset({
'gvsdsdk',
})
def _get_saas_db(self):
from django.conf import settings
return getattr(settings, 'GVSDSDK_SAAS_DB_ALIAS', 'saas')
def _is_read_only(self):
from django.conf import settings
return getattr(settings, 'GVSDSDK_SAAS_READ_ONLY', True)
def _is_gvsdsdk_model(self, model):
"""判断模型是否属于 gvsdsdk"""
# 按模块路径判断
module = getattr(model, '__module__', '')
if module in self._GVSDSDK_MODULES or module.startswith('gvsdsdk.'):
return True
# 按 app_label 判断
app_label = getattr(model._meta, 'app_label', '')
if app_label in self._GVSDSDK_APP_LABELS:
return True
return False
def db_for_read(self, model, **hints):
if self._is_gvsdsdk_model(model):
return self._get_saas_db()
return None
def db_for_write(self, model, **hints):
if self._is_gvsdsdk_model(model):
if self._is_read_only():
raise RuntimeError(
"gvsdsdk SAAS database is read-only for sub-servers. "
"Set GVSDSDK_SAAS_READ_ONLY=False to allow writes."
)
return self._get_saas_db()
return None
def allow_relation(self, obj1, obj2, **hints):
# 允许同一数据库内的关联
db1 = self.db_for_read(obj1.__class__)
db2 = self.db_for_read(obj2.__class__)
if db1 and db2 and db1 == db2:
return True
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
# gvsdsdk 模型不迁移managed=False 或由主服务器管理)
if app_label in self._GVSDSDK_APP_LABELS:
return db != self._get_saas_db()
return None