从 Flask 蓝图访问数据库

dex*_*per 3 python sqlalchemy blueprint flask

我正在使用 Flask 和 SQLAlchemy 构建 RESTful API 应用程序,并尝试应用蓝图模式来注册我的路线。蓝图 @route 函数包含对数据库会话对象的引用。我希望以“代理风格”访问它 - 您可以使用app.current_app访问 Flask.app ,但我的实现不起作用。

wsgi.py:(从这里运行)

# imports
from wallet.walletapp import main

app = create_app(url='sqlite:///./test.db')
dbase = Database(url='sqlite:///./test.db')

db = dbase.create_session()
models.Base.metadata.create_all(bind=dbase.engine)

abort = Abort(app, db)
app.config['database'] = db
app.config['abortion'] = abort
with app.app_context:
    app.register_blueprint(main)
app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)

钱包应用程序.py

main = Blueprint('main', __name__)
app = current_app
db = current_app.config['database']
abort = current_app.config['abortion']

# Get wallet list
@main.route('/v1/wallets', methods=['GET'])
def get_wallets():
    '''
    Get all the wallets and their balances
    '''
    wallets = db.query(models.Wallet).all()
    result = wallets_schema.dump(wallets)

    resp = cook_response(app, {'wallets': result})

    return resp, 200
Run Code Online (Sandbox Code Playgroud)

这样我就得到了一个RuntimeError: Workout of application context Early - on importing stage in wsgi.py:

  File "/wsgi.py", line 5, in <module>
        from wallet.walletapp import main
  File "/walletapp.py", line 26, in <module>
        db = current_app.config['database']
  File "/env/lib/python3.9/site-packages/werkzeug/local.py", line 422, in __get__
        obj = instance._get_current_object()
  File "/env/lib/python3.9/site-packages/werkzeug/local.py", line 544, in _get_current_object
        return self.__local()  # type: ignore
  File "env/lib/python3.9/site-packages/flask/globals.py", line 47, in _find_app
        raise RuntimeError(_app_ctx_err_msg)
Run Code Online (Sandbox Code Playgroud)

这背后的想法是让walletapp.py作为真正的蓝图更加灵活:例如,在单元测试中轻松地将工作数据库交换为虚拟数据库。

总之:

在walletapp.py中定义或导入数据库(db)使模块不可插入:我只能使用其中导入或声明的数据库。如何重写我的代码以使其按预期工作?

这个问题与我的问题有直接联系,但答案并不复杂:使用 Flask-SQLAlchemy 或“在上下文之前声明数据库对象,然后导入它”,我尝试在这里实现。我不想使用 Flask-SQLAlchemy 模式(因为本文中描述的一些要点)。

我是 Flask 的新手,所以如果问题过时、过度或错误,请友善,否则)我觉得应该有一些声音和清晰的解决方案,但无法触及它的方式。

dex*_*per 5

我找到了解决方案。将其发布在这里,以防有人遇到同样的问题。

首先,我这里有一个错误:

app.app_context:
Run Code Online (Sandbox Code Playgroud)

我应该这样称呼上下文

app.app_context():
Run Code Online (Sandbox Code Playgroud)

感谢您的回答

其次,我应该从app.app_context() 内的wsgi.py导入路由:

# defining app and db
abort = Abort(app, db)
app.config['database'] = db
app.config['abortion'] = abort
with app.app_context():
    from wallet import walletapp
    app.register_blueprint(walletapp.main)
app.run(debug=True)
Run Code Online (Sandbox Code Playgroud)

最后,我像这样重写了 walletapp.py

app = current_app
    with app.app_context():
        db = current_app.config['database']
        abort = current_app.config['abortion']
        main = Blueprint('main', __name__)
# then goes @main.routes
Run Code Online (Sandbox Code Playgroud)

在此模式下,代码运行良好。