动态切换数据库链接
如果你有多个数据库链接,并且在启动服务之前没有写入相关的配置文件,这种情况下该如何使用动态的增加数据库链接并使用呢?
前置条件
这里假设你的数据库配置信息已经写入默认的数据库中(这里暂且称为应用程序数据库,或者AppDB),在AppDB 中的某张表中存储着其他的数据库链接信息(这里暂且称为应用程序扩展数据库,或者AppExtendDB)
Flask
使用 Flask-SQLAlchemy 创建 model
python
# 使用 Flask-SQLAlchemy 创建 model
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
# 查询所有用户,使用 AppDB 的数据库链接
User.query.all()
def new_session(url):
engine = create_engine(url)
# 创建一个新的会话
Session = sessionmaker(bind=engine)
return Session
# 创建一个 AppExtendDB 的数据库链接
db_new_session= new_session(url)()
# 查询 AppExtendDB 中的 user 信息,其他诸如表/列必须存在的基本要求不做赘述
User.query.with_session(bb).all()
# 类似的只有 AppExtendDB 中存在 UserExtend
# 所以 UserExtend.query.all() 就会报错
# 必须使用 UserExtend.query.with_session(bb).all()
class UserExtend(db.Model):
id = db.Column(db.Integer, primary_key=True)
age= db.Column(db.String(80), unique=True, nullable=False)
phone= db.Column(db.String(120), unique=True, nullable=False)
Django
使用 DatabaseRouter
- 创建一个数据库路由类,用于根据需要切换数据库连接。在你的应用程序中创建一个名为 database_router.py 的文件,并添加以下内容:
python
class DatabaseRouter:
def db_for_read(self, model, **hints):
# 根据需要返回读取操作的数据库别名
if model._meta.app_label == 'AppDB':
return 'AppDB url'
if model._meta.app_label == 'AppExtendDB':
return 'AppExtendDB url'
return None
def db_for_write(self, model, **hints):
# 根据需要返回读取操作的数据库别名
if model._meta.app_label == 'AppDB':
return 'AppDB url'
if model._meta.app_label == 'AppExtendDB':
return 'AppExtendDB url'
return None
def allow_relation(self, obj1, obj2, **hints):
# 允许关系操作
return True
def allow_migrate(self, db, app_label, model_name=None, **hints):
# 允许迁移操作
return True
- 在 settings.py 文件中配置数据库路由:
python
DATABASE_ROUTERS = ['your_app.database_router.DatabaseRouter']
-
修改你的代码,比如在中间件中
def process_view(request, view_func, view_args, view_kwargs): default_dict = copy.deepcopy(settings.DATABASES['default']) default_dict.update({ 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'db name', 'USER': 'db user', 'PASSWORD': 'db pwd', 'HOST': 'db host', 'PORT': '5432', }) settings.DATABASES['AppExtendDB'] = default_dict
-
查询
方式一
UserExtend._meta.app_label = "AppExtendDB"
UserExtend.objects.all()方式二
UserExtend.objects.using('AppExtendDB').all()
到此结 DragonFangQy 2023.10.31