You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Pytest在生产环境测试时SQLAlchemy提示未设置SQLALCHEMY_DATABASE_URI的排查方法

问题

我有一个基于Flask的应用,采用SQLAlchemy、应用工厂模式,通过config.py管理配置,同时搭建了自托管GitHub Runner的CI流水线,用Pytest做测试。本地测试全部通过,但在服务器Runner上运行时,SQLAlchemy抛出错误提示未设置SQLALCHEMY_DATABASE_URI,而该配置已经在应用工厂里定义了,该怎么排查?

相关代码文件

extensions.py

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

# global state for DB connection
db = SQLAlchemy()
migrate = Migrate()

应用工厂(init.py)

from flask import Flask
from app.blueprints.main import main
from app.blueprints.api import api
from flask_cors import CORS
from app.extensions import db, migrate

# application factory method used to create the flask app with all the blueprints and extensions
def create_app(config=None):
    #creates the app
    app = Flask(__name__)

    # set config
    if config is None:
        app.config.from_object('config.BaseConfig')
    else:
        app.config.from_object(config)
    
    #sets cors to accept everything
    CORS(app, resources={r"*": {"origins": "*"}})

    # init sql alchemy db
    db.init_app(app)
    migrate.init_app(app, db)
        
    #registers the blueprints
    app.register_blueprint(main)
    app.register_blueprint(api)

    #returns the app
    return app

config.py

from dotenv import load_dotenv
import os
load_dotenv()

# add app configs here, see __init__.py for how to use them

class BaseConfig(object):
    DEBUG = False
    TESTING = False
    SECRET_KEY = os.getenv("SECRET_KEY")

    SQLALCHEMY_DATABASE_URI = os.getenv("SQLALCHEMY_DATABASE_URI")
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class TestingConfig(BaseConfig):
    TESTING = True

Pytest夹具

@pytest.fixture
def app():
    app = create_app("config.TestingConfig")
    return app

错误信息

GitHub Actions控制台输出的错误:

if not engine_options:
>           raise RuntimeError(
                "Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set."
            )
E           RuntimeError: Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set.

../../_tool/Python/3.11.3/x64/lib/python3.11/site-packages/flask_sqlalchemy/extension.py:307: RuntimeError
____________ ERROR at setup of test_FlightData_creates_successfully ____________

    @pytest.fixture
    def app():
>       app = create_app("config.TestingConfig")
排查方案
  • 验证Runner环境变量加载情况:自托管Runner可能没正确读取到.env变量或系统环境变量。在CI测试步骤前添加命令打印变量(如echo $SQLALCHEMY_DATABASE_URI),确认变量是否存在。同时检查Runner上代码仓库的根目录是否有.env文件,load_dotenv()默认只加载该路径的文件。
  • 给TestingConfig设置独立测试数据库:测试环境不建议依赖外部环境变量,直接在TestingConfig中硬编码内存数据库地址,避免依赖外部配置:
    class TestingConfig(BaseConfig):
        TESTING = True
        SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:"
    
    这样既不需要依赖外部环境,也能防止误操作生产数据库。
  • 调整环境变量加载时机:load_dotenv()在config.py导入时执行,如果Runner的环境变量是后续步骤才设置的,会导致加载失败。把load_dotenv()移到应用工厂函数内部,确保创建应用前加载变量:
    def create_app(config=None):
        from dotenv import load_dotenv
        load_dotenv()
        app = Flask(__name__)
        # 后续配置代码
    
  • 核对依赖版本一致性:本地和Runner上的Flask-SQLAlchemy版本可能存在差异,新版本的配置检查逻辑更严格。把requirements.txt中的包版本固定,确保两边环境一致。
  • 调试应用配置:在Pytest夹具中添加打印配置的代码,查看CI日志确认SQLALCHEMY_DATABASE_URI是否被正确读取:
    @pytest.fixture
    def app():
        app = create_app("config.TestingConfig")
        print("SQLALCHEMY_DATABASE_URI:", app.config.get("SQLALCHEMY_DATABASE_URI"))
        return app
    

内容的提问来源于stack exchange,提问作者Graham Billington

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 00:22:50