我如何将TemporaryUploadedFile传递给芹菜任务



我有一个代码:

def post(self, request, *args, **kwargs):
    file = request.FILES["import_file"]
    # create a tast with celery and save ID of the task
    task_id = importing.delay(file).id
    return Response({"task_id": task_id}, content_type="application/json")

当类型(文件)是TemporaryUploadedFile时,我有错误,因为该文件无法写入redis。

我可以取这个临时文件的名字,并将这个名字保存到Redis中。然后芹菜工人可以从redis中获得这个名称并读取文件。但我不确定:在芹菜工人从redis获得其名称之前,该文件能否被删除?

request_finished信号一发出,TemporaryUploadedFile就会关闭并移除。当你的Celery工作人员找到该文件时,该文件很可能不再存在。

您应该将文件复制到一个持久的位置,并在完成后让Celery清理文件。

    def close(self):
        try:
            return self.file.close()
        except OSError as e:
            if e.errno != errno.ENOENT:
                # Means the file was moved or deleted before the tempfile
                # could unlink it.  Still sets self.file.close_called and
                # calls self.file.file.close() before the exception
                raise

根据TemporaryUploadedFile的close方法的源代码,如果临时文件被移动,它不会被关闭,所以你可以移动它,并将它的新路径传递给芹菜任务,然后在芹菜任务完成时自己删除它。通过这种方式,您将节省将文件复制到持久位置的时间和资源。

    import os
    from django.core.files import uploadedfile
    file = request.FILES["import_file"]
    new_path = '/tmp/import_file'
    if isinstance(file, uploadedfile.TemporaryUploadedFile):
        os.rename(file.file.name, new_path)
    else:    # Deal with InMemoryUploadedFile
        with open(new_path, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)
    task_id = importing.delay(new_path).id

相关内容

  • 没有找到相关文章

最新更新