Flask - 在请求之间将值存储在内存中

时间:2015-07-14 13:10:02

标签: python ajax rest flask python-requests

我有一个单页面应用程序 - 前端的Angularjs和后端的烧瓶让用户上传文件(xlsx,csv ...),然后交互式分析/查询文件

基本上,用户在首次上传时将文件加载到内存中,然后随后的ajax调用将在内存中接入此文件。我不知道如何在后续请求(ajax)之间将文件保存在内存中。

g变量在每次请求后都会被删除,如果我理解用于访问请求中的值(通常由before_request设置并且可通过views

获取

请求上下文是请求的本地。我确实设法在current_app上设置了值,然后能够在随后的ajax调用中访问它

# On my first file upload, i load the file into memory
and set it to a variable on current_app:

from flask import current_app
@app.route('/upload', methods =['POST'])
def upload():
   ...
   upload file into memory
   ...
   current_app.file = file_in_memory



@app.route('/subsequent_call')
def subsequent():
    # i'm able to access the file in memory through 
    the current_app.file which i set earlier

    return current_app.file.number_of_lines()

这种将文件存储在current_app上的内存中的方法看起来不对,感觉太脏/太乱了。这会有规模吗?

我可以在每次请求后挑选文件并在每次请求时将其拉回来。但是,当用户以交互方式查询数据时,每次存储/腌制和重新获取文件到内存中似乎太沉重/低效

还有其他优雅/正确的方法吗,app_context,werkzeug当地人等?或者我在想这一切都错了?

2 个答案:

答案 0 :(得分:2)

如果您的网络服务器产生多个流程(工作人员)来处理请求,那么以这种方式存储文件将无法工作,这就是大多数生产服务器的工作方式。

如果服务器负载增加,继续将文件对象保留在内存中不会扩展,您可以将文件保存在文件系统中并在每次请求期间初始化pandas对象。您可以将其与加载腌制对象进行比较,看看哪个更快。你还必须考虑酸洗的开销而不仅仅是去除油漆。

编辑:解释为什么它不能在生产中工作

Gunicorn和类似的网络服务器可能会产生多个工作者,除非你在限制配置,工作者本质上是一个单独的进程,每个进程都有自己的python执行环境。因此,假设您的第一个请求命中worker1,并在该过程中创建变量current_app.file = file_in_memory。然后你的第二个请求可能会命中worker2,它有自己的python执行环境,你的变量不可用,因为它们不是跨进程共享的。实际上,该变量中可能存在值,但它属于不同的用户请求。

总而言之

  1. 不保证请求之间有相同的对象
  2. 它可能会被同时使用您的应用的其他用户覆盖

答案 1 :(得分:0)

尽管我很晚才回答这个问题,但这仍然对我们许多人有帮助。 为了在请求之间共享值,您应该信任使用缓存。使用flask-cache和redis作为数据库,可以很容易地实现flask中的缓存。这将是最有效,最可靠的方法。阅读任何有关在烧瓶中实现redis作为缓存db的文章,以供进一步参考。