python Flask项目使用SQLalchemy连接数据库时,出现RuntimeError:Working outside of application context.的解决过程记录

03-18 8729阅读 0评论

一、问题出现

在使用python的Flask框架跟着教程编写项目时,我跟着教程使用了三个文件来组织,分别是main.py(主程序),module.py(数据库模型),controller.py(蓝图模块程序,用Blueprint衔接)

python Flask项目使用SQLalchemy连接数据库时,出现RuntimeError:Working outside of application context.的解决过程记录 第1张
(图片来源网络,侵删)

在主程序中,创建app、SQLalchemy实例对象db并将二者绑定

app = Flask(__name__, static_url_path='/')
# 配置app参数
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:password@localhost:3306/ayangnote?charset=utf8'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # True跟踪数据库的修改,及时发送信号
# 实例化db对象,绑定flask的app
db = SQLalchemy(app)

在module.py中,导入主程序中的db和app,创建子类Users作为查询表,并定义数据库查询的方法

from main import db # 直接引用main模块中的全局变量
    
class Users(db.Model):
    __table__ = Table('users', db.metadata, autoload_with=db.engine, mysql_bind=db.engine)
    def find_user_by_id(self, userid):
        row = db.session.query(Users).filter(Users.userid == userid).first()
        return row
    def find_user_by_id2(self, userid):
        row = Users.query.filter(Users.userid == userid).first()
        return row

controller.py与主程序通过Blueprint衔接,并且创建查询接口和指定操作

但我写完后,运行起来报错RuntimeError: Working outside of application context.表示缺少上下文

二、试图修改

在查询相关解决方案后,我试图理解了一下Flask框架上下文机制的原理,增加代码with app.app_context():

python Flask项目使用SQLalchemy连接数据库时,出现RuntimeError:Working outside of application context.的解决过程记录 第2张
(图片来源网络,侵删)

参考链接:关于flask中 RuntimeError: Working outside of application context 引发的问题(flask中的上下文机制)

module修改1.py

from main import db,app # 直接引用main模块中的全局变量
# 创建上下文
with app.app_context():
    class Users(db.Model):
    __table__ = Table('users', db.metadata, autoload_with=db.engine, mysql_bind=db.engine)
    def find_user_by_id(self, userid):
        row = db.session.query(Users).filter(Users.userid == userid).first()
        return row
    def find_user_by_id2(self, userid):
        row = Users.query.filter(Users.userid == userid).first()
        return row

这样修改完,仍然在页面报错RuntimeError: The current Flask app is not registered with this 'SQLAlchemy' instance. Did you forget to call 'init_app', or did you create multiple 'SQLAlchemy' instances?

三、解决方案

我意识到是两个文件中应用的SQLAlchemy对象可能并非同一个(现在仍然不知道为啥,如有人知道求告知!)最终在chatgpt的帮助下得出一个比较笨,但很简单的解决方案:

解决方案如下:

具体来说,SQLAlchemy 对象需要知道它将要与哪个 Flask 应用程序实例绑定。如果在不同的 Python 文件中创建了不同的 Flask 实例,并且在每个文件中都创建了一个 SQLAlchemy 实例,则会导致这个问题。为了解决这个问题,你可以考虑将 SQLAlchemy 实例单独放在一个模块中,然后在需要使用它的地方导入它。同时,在 main.py 中导入其他模块时,也要确保它们使用的是相同的 Flask 实例。

以下是一个可能的解决方案:

  1. 在一个单独的文件(例如 database.py)中创建一个 SQLAlchemy 实例,代码如下:
    from flask_sqlalchemy import SQLAlchemy
    db = SQLAlchemy()
    
  2. 在主程序 main.py 中导入 db 对象并绑定到 Flask 应用程序实例:
    from flask import Flask
    from database import db
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:password@localhost:3306/ayangnote?charset=utf8'
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db.init_app(app)
    
  3. 在其他模块中导入 db 对象,并确保它们使用的是相同的 Flask 应用程序实例。例如,在 module.py 中:
    from database import db
    with app.app_context():
        class Users(db.Model):
            ...
    

    这样,所有模块都将使用相同的 Flask 应用程序实例和 SQLAlchemy 实例,从而避免出现不同实例之间的冲突。

最后鸣谢chatgpt,呜呜


免责声明
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明。
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所
提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何
损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在
转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并白负版权等法律责任。

手机扫描二维码访问

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,8729人围观)

还没有评论,来说两句吧...

目录[+]