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

时间:2015-11-25 15:15:04

标签: python django redis celery temporary-files

我有一个代码:

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获取名称之前,文件是否可以删除?

2 个答案:

答案 0 :(得分:1)

TemporaryUploadedFile信号一旦被触发,就会关闭并移除cursor = conn.execute("SELECT ID,ResidentTitle,ResidentForname FROMResidents") -------------------------------------------------------------------^ 。当您的Celery工作人员到达时,该文件很可能不再存在。

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

答案 1 :(得分:0)

    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方法的源代码,临时文件被移动不会关闭,所以你可以移动它并将它的新路径传递给celery任务,然后在celery任务完成时自己删除它. 这样,您将节省将文件复制到永久位置的时间和资源。

    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