Flask中同一蓝图多次注册绑定不同数据库复用相同模型如何实现
实现方案
第一步:配置多数据库绑定
先在Flask配置中声明所有国家的数据库绑定关系,使用Flask-SQLAlchemy原生的SQLALCHEMY_BINDS特性实现多库管理:
app.config['SQLALCHEMY_DATABASE_URI'] = '默认数据库连接地址' app.config['SQLALCHEMY_BINDS'] = { 'pt': 'mysql://账号:密码@地址/foobar_pt', 'br': 'mysql://账号:密码@地址/foobar_br', 'mx': 'mysql://账号:密码@地址/foobar_mx', # 新增国家仅需要在这里加对应配置即可 }
第二步:编写可复用的蓝图工厂
因为同一个Blueprint实例多次注册会出现endpoint冲突问题,所以用工厂函数批量生成对应国家的蓝图实例,同时通过蓝图前置钩子动态绑定对应数据库,完全复用原有的业务逻辑:
from flask import g, current_app def create_country_api(country_code: str): # 蓝图名称增加国家码前缀,保证全局唯一 api = Blueprint(f'api_{country_code}', __name__) # 蓝图请求前置钩子,自动绑定对应国家的数据库 @api.before_request def bind_country_db(): g.current_country = country_code # 给当前数据库会话绑定对应国家的数据库引擎 db.session.bind = db.get_engine(current_app, bind=country_code) # 原有接口逻辑完全复用,无需修改 @api.route('/products') def product_get(): result = Product.query.all() # 格式转换逻辑和原有一致即可 return jsonify([{"id": item.id, "name": item.name} for item in result]) return api
第三步:批量注册国家蓝图
不需要逐个手写注册逻辑,批量遍历国家列表注册即可:
# 国家列表和配置中的bind键保持一致 COUNTRY_LIST = ['pt', 'br', 'mx'] for country in COUNTRY_LIST: app.register_blueprint( create_country_api(country), url_prefix=f'/{country}' )
补充必要的资源回收逻辑
避免数据库连接泄漏,增加请求结束后的会话回收钩子:
@app.teardown_request def clear_db_session(exception=None): db.session.remove()
注意事项
- 所有国家的数据库表结构必须完全一致,否则会出现查询报错
- 如果需要跨库操作,不要使用当前会话直接查询,单独用
db.session(bind=对应bind键)创建独立会话操作
内容的提问来源于stack exchange,提问作者Sergio A. Kessler
相关产品推荐
相关产品推荐

