访问Blueprint应用程序中的Flask全局变量

时间:2018-05-08 12:01:29

标签: python python-3.x flask

我的源代码具有以下结构:

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中设置和访问全局变量?

2 个答案:

答案 0 :(得分: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内创建它?

答案 1 :(得分:2)

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

db.py

import <postgresql dependencies>

def get_db():
   db = PostgreSQL()
   # config here
   return db

main.py

from flask import Flask, g

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