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

jet*_*com 7 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()
Run Code Online (Sandbox Code Playgroud)

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

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

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

shr*_*yas 3

如果您的网络服务器生成多个进程(工作进程)来处理请求,则以这种方式存储文件将不起作用,而这就是大多数生产服务器的工作方式。

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

编辑:解释为什么它在生产中不起作用

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

所以总而言之

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