如何在Flask应用运行时修改配置变量实现测试/生产数据库切换?
可行解决方案
核心原则:不要修改全局app.config(Flask应用配置是全局共享的,修改后会影响所有在线用户),改为基于用户会话/请求维度动态绑定数据库连接配置,全程无需调整Apache部署规则。
1. 预加载两套数据库配置
修改初始化代码,不再仅加载单套配置,而是把两套配置都预存在应用属性中:
# __init__.py 代码调整 from project.config import configTest, configProd # 保留默认配置加载逻辑不影响原有功能 app.config.from_object('project.config.configTest') # 新增:预存两套环境的数据库配置 app.db_config_map = { "test": configTest, "prod": configProd }
2. 存储用户选择的环境标识
在登录表单新增环境选择下拉框,用户提交后将选择的环境标识存入每个用户独立的session中:
# 登录接口逻辑示例 @app.route('/login', methods=['POST']) def handle_login(): # 原有账号密码验证逻辑省略 # 读取前端传的用户选择的环境参数,默认走测试环境 user_selected_env = request.form.get("env", "test") session["current_env"] = user_selected_env # 后续登录跳转逻辑省略
3. 动态获取数据库连接
如果使用SQLAlchemy作为ORM,推荐用多绑定方案实现动态切换,不需要重构原有数据库操作逻辑:
# 初始化阶段预配置两个数据库绑定 app.config["SQLALCHEMY_BINDS"] = { "test": f"mysql+pymysql://{configTest.MYSQL_USER}:{configTest.MYSQL_PASSWORD}@{configTest.MYSQL_HOST}:{configTest.MYSQL_PORT}/{configTest.MYSQL_DB}", "prod": f"mysql+pymysql://{configProd.MYSQL_USER}:{configProd.MYSQL_PASSWORD}@{configProd.MYSQL_HOST}:{configProd.MYSQL_PORT}/{configProd.MYSQL_DB}" } # 数据库操作时根据当前用户的环境选择指定绑定即可 def get_user_list(): current_env = session.get("current_env", "test") return User.query.using_bind(current_env).all()
4. 可选无感知切换方案:基于域名自动匹配
如果不需要用户手动选择,也可以配置两个域名(如test.yourdomain.com、prod.yourdomain.com)同时指向当前Apache部署的应用,通过钩子自动识别环境:
@app.before_request def auto_set_env(): if request.host.startswith("prod."): session["current_env"] = "prod" else: session["current_env"] = "test"
注意事项
- 禁止直接修改全局app.config的数据库配置,会导致所有用户的环境被同时篡改,引发生产数据安全问题
- 建议增加权限校验,仅授权用户可以切换到生产环境
- 非请求上下文的后台任务不要依赖session存储的环境标识,需要单独传入环境参数
内容的提问来源于stack exchange,提问作者rajat yadav
相关产品推荐
相关产品推荐

