參考文檔
https://www.jb51.net/article/174365.htm
https://gist.github.com/trustrachel/6828122#file-routing-py
步驟
在配置中添加以下配置
SQLALCHEMY_DATABASE_URI = 'xxx'
SQLALCHEMY_BINDS = {
'xxx',
'xxx',
}
改寫session
from flask_sqlalchemy import SQLAlchemy, get_state
import sqlalchemy.orm as orm
from functools import partial
import logging
log = logging.getLogger(__name__)
class AutoRouteSession(orm.Session):
def __init__(self, db, autocommit=False, autoflush=False, **options):
self.app = db.get_app()
self._model_changes = {}
orm.Session.__init__(self, autocommit=autocommit, autoflush=autoflush,
bind=db.engine,
binds=db.get_binds(self.app), **options)
def get_bind(self, mapper=None, clause=None):
"""
根據配置及讀寫操作,自動更改數據庫引擎
Args:
mapper:
clause:
Returns:
"""
try:
state = get_state(self.app)
except (AssertionError, AttributeError, TypeError) as err:
log.info("獲取配置失敗,使用默認數據庫:{}".format(err))
return orm.Session.get_bind(self, mapper, clause)
# 如果沒有設置SQLALCHEMY_BINDS,則默認使用SQLALCHEMY_DATABASE_URI
if state is None or not self.app.config['SQLALCHEMY_BINDS']:
if not self.app.debug:
log.debug("未獲取數據庫綁定信息(SQLALCHEMY_BINDS),使用默認數據庫")
return orm.Session.get_bind(self, mapper, clause)
# insert、update、delete操作使用master
elif self._flushing:
log.debug("當前使用master")
return state.db.get_engine(self.app, bind='master')
# 其他操作使用slave
else:
log.debug("當前使用slave")
return state.db.get_engine(self.app, bind='slave')
class AutoRouteSQLAlchemy(SQLAlchemy):
def create_scoped_session(self, options=None):
"""
用於工廠類創建session
Args:
options:
Returns:
"""
if options is None:
options = {}
scopefunc = options.pop('scopefunc', None)
return orm.scoped_session(
partial(AutoRouteSession, self, **options), scopefunc=scopefunc
)
實例化
db = AutoRouteSQLAlchemy()