使用Django Celery任务处理大文件

3

我的目标是使用Celery处理通过Django表单上传的大型CSV文件。当文件大小小于SETTINGS.FILE_UPLOAD_MAX_MEMORY_SIZE时,我可以将表单的cleaned_data变量传递给Celery任务,并使用以下代码读取文件:

@task
def taskFunction(cleaned_data):
    for line in csv.reader(cleaned_data['upload_file']):
        MyModel.objects.create(field=line[0])

然而,当文件大小超过上述设置时,我会收到以下错误:
expected string or Unicode object, NoneType found

堆栈跟踪显示了在pickle过程中发生错误的位置:

return dumper(obj, protocol=pickle_protocol)

看起来,当从临时文件中读取上传的文件时,pickle会失败。

解决这个问题的简单方法是增加FILE_UPLOAD_MAX_MEMORY_SIZE。但是,我想知道是否有更好的方法来管理这个问题?


一个自定义的存储处理程序会更加清晰。 - Paulo Scardine
1个回答

0

将其保存到临时文件中,然后将文件名传递给celery。处理完成后删除。


1
在Celery工作进程处理临时文件之前,可以将其删除吗? - drlexa
我不确定你在问什么...显然在读取文件之前不能删除它。不要使用标准库中的tempfile.mkstemp,因为它可能会自动被删除,并且其他用户无法读取。只需创建一个普通文件,在处理完毕后手动删除它。或者如果方便的话,可以使用django.db.models.FileField。 - joshua
1
如果Celery与您的主应用程序在同一台服务器上运行,则此解决方案有效。如果您在其他服务器上运行,则考虑上传到像S3这样的公共存储。 - stupidbodo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接