在Flask中使用全局变量(flask.g)

3 投票
1 回答
6973 浏览
提问于 2025-04-18 10:00

我想在服务器上启动一个数据加载的过程,这个过程大约需要10到15分钟。在这个过程中,我希望能不断地通过ajax请求服务器,告诉用户数据加载的进度。

我已经把所有的东西都弄好了,包括数据加载和ajax请求等等……但是我在状态的传递上遇到了一些问题。我使用了一个全局的变量g,像这样:

这个函数最开始是由客户端调用的。同时,客户端还会每5秒发一次请求(为了简单起见,我把一些代码替换成了一个简单的时间循环):

@app.route('/updatedb')
def updatedb():
    while True:
        g.songcounter = time.strftime("%I:%M:%S")
        print(g.songcounter)
        time.sleep(1)
    models.add_collection("/media/store/Music")
    return 

这是客户端每5秒调用的内容:

@app.route('/dbstatus')
def dbstatus():
    if g.songcounter:
        print("status:%s" % g.songcounter)
    else:
        print("status: no")
    k = g.songcounter #time.strftime("%I:%M:%S")
    return render_template("dbstatus.html", timestamp=k)

……然后我得到的结果是,g.songcounter在更新线程之外是无效的……这可能是合理的,但我该怎么办呢?

127.0.0.1 - - [17/Jun/2014 07:41:31] "GET /dbstatus HTTP/1.1" 500 -
07:41:31
07:41:32
127.0.0.1 - - [17/Jun/2014 07:41:33] "GET /dbstatus HTTP/1.1" 500 -
07:41:33
127.0.0.1 - - [17/Jun/2014 07:41:34] "GET /dbstatus HTTP/1.1" 500 -
07:41:34
07:41:35
127.0.0.1 - - [17/Jun/2014 07:41:36] "GET /dbstatus HTTP/1.1" 500 -
07:41:36
07:41:37
127.0.0.1 - - [17/Jun/2014 07:41:38] "GET /dbstatus HTTP/1.1" 500 -
07:41:38
127.0.0.1 - - [17/Jun/2014 07:41:39] "GET /dbstatus HTTP/1.1" 500 -
07:41:39

1 个回答

2

你不能像使用 g 这样的上下文对象来做这个。上下文对象只在一个线程中存在,并且在请求开始或结束时会发生变化。想了解更多细节,可以看看这些链接:http://flask.pocoo.org/docs/appcontext/http://flask.pocoo.org/docs/reqcontext/,或者另一个有趣的问题 Flask 的上下文栈有什么用?

所以在你的情况下,最好使用其他共享存储,比如用用户或会话 ID 作为键:

  • 全局 dict
  • 服务器端会话
  • 缓存 / redis / memcached
  • 数据库
  • 等等

撰写回答