【问题标题】:Access to Flask Global Variables in Blueprint Apps在蓝图应用程序中访问 Flask 全局变量
【发布时间】:2018-10-18 09:01:50
【问题描述】:

我的源代码有这样的结构:

main.py:

from flask import Flask, g
app = Flask(__name__)
with app.app_context():
    g.my_db = PostgreSQL()
    app.register_blueprint(my_app, url_prefix="/my_app")

my_app.py:

from flask import Blueprint, g
my_app = Blueprint("my_app", __name__)
@my_app.route("/")
def index():
    return g.my_db.fetch_all()   <<< ERROR

但它显示此错误:

AttributeError: '_AppCtxGlobals' object has no attribute 'my_db'

即使我尝试在应用程序上下文之外使用g,它也会显示此错误:

RuntimeError: Working outside of application context.

那么如何在 Flask 中设置和访问全局变量呢?

【问题讨论】:

    标签: python python-3.x flask


    【解决方案1】:

    g 在您尝试使用它的方式上并不持久。每次需要时编写一个函数来创建一个连接。最好使用像 Flask-SQLAlchemy 这样的数据库扩展来为您管理连接。

    db.py:

    import <postgresql dependencies>
    
    def get_db():
       db = PostgreSQL()
       # config here
       return db
    

    main.py:

    from flask import Flask
    
    app = Flask(__name__)
    app.register_blueprint(my_app, url_prefix="/my_app")
    

    my_app.py:

    from flask import Blueprint, g
    from db import get_db
    
    my_app = Blueprint("my_app", __name__)
    
    @my_app.route("/")
    def index():
        db = get_db()
        data = db.fetch_all()
        db.close()
        return data
    

    【讨论】:

      【解决方案2】:

      发生这种情况是因为当上下文 (with app.app_context()) 结束 (doc) 时数据丢失。

      在上下文中,一切正常:

      from flask import Flask, g
      app = Flask(__name__)
      with app.app_context():
          g.my_db = 'database ok'
          print(g.my_db)
      
      # >>> this prints 'database ok'
      

      但是在外面,你不能访问该属性:

      from flask import Flask, g
      app = Flask(__name__)
      with app.app_context():
          g.my_db = 'database ok'
      
      print(g.my_db)
      
      # >>> this throws RuntimeError: Working outside of application context
      

      即使你创建了一个新的上下文:

      from flask import Flask, g
      app = Flask(__name__)
      with app.app_context():
          g.my_db = 'database ok'
      
      with app.app_context():
          print(g.my_db)
      
      >>> this throws AttributeError: '_AppCtxGlobals' object has no attribute 'my_db'
      

      最好的调用应该是在上下文之前声明数据库对象,然后导入它。或者你可以直接在my_app.py 里面创建你需要的地方?

      【讨论】:

      • 谢谢,我已经更新了我的问题。请举个例子好吗?
      • 不知道你项目的结构,哪里需要数据库对象,只在你的模块my_app
      • 在项目的所有模块(应用程序)中。
      • 很难说出更多信息来避免循环导入的噩梦。不要将数据库对象存储在g 中。例如,您可以在应用程序根文件夹的__init__.py 中创建它(如果有的话)。您的问题代码不完整,无法准确重现和改进您正在使用的结构。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      相关资源
      最近更新 更多