Django 将 excel 文件发送到 Celery 任务。内存上传文件错误
Django send excel file to Celery Task. Error InMemoryUploadedFile
我有后台进程 - 读取 excel 文件并从此文件保存数据。我需要在后台进程中读取文件。但是我有错误 InMemoryUploadedFile
。
我的代码
def create(self, validated_data):
company = ''
file_type = ''
email = ''
file = validated_data['file']
import_data.delay(file=file,
company=company,
file_type=file_type,
email=email)
我的方法看起来像
@app.task
def import_data(
file,
company,
file_type,
email):
// some code
但是我有错误InMemoryUploadedFile
。
我怎样才能将文件无误地发送到 cellery?
当您延迟任务时,Celery 将尝试序列化参数,在您的情况下,该参数包含一个文件。
无法序列化文件,尤其是内存中的文件。
因此,要解决此问题,您必须保存文件并将文件路径传递给延迟函数,然后在那里读取文件并进行计算。
Celery 不知道如何序列化文件对象等复杂对象。但是,这可以很容易地解决。我所做的是 encode/decode 将文件转换为其 Base64 字符串表示形式。这允许我直接通过 Celery 发送文件。
以下示例展示了如何(我有意将每个转换分开放置,尽管这可以以更 pythonic 的方式安排):
import base64
import tempfile
# (Django, HTTP server)
file = request.FILES['files'].file
file_bytes = file.read()
file_bytes_base64 = base64.b64encode(file_bytes)
file_bytes_base64_str = file_bytes_base64.decode('utf-8') # this is a str
# (...send string through Celery...)
# (Celery worker task)
file_bytes_base64 = file_bytes_base64_str.encode('utf-8')
file_bytes = base64.b64decode(file_bytes_base64)
# Write the file to a temporary location, deletion is guaranteed
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_file = os.path.join(tmp_dir, 'something.zip')
with open(tmp_file, 'wb') as f:
f.write(file_bytes)
# Process the file
这对于大文件来说效率不高,但对于 small/medium 大小的临时文件来说非常方便。
我有后台进程 - 读取 excel 文件并从此文件保存数据。我需要在后台进程中读取文件。但是我有错误 InMemoryUploadedFile
。
我的代码
def create(self, validated_data):
company = ''
file_type = ''
email = ''
file = validated_data['file']
import_data.delay(file=file,
company=company,
file_type=file_type,
email=email)
我的方法看起来像
@app.task
def import_data(
file,
company,
file_type,
email):
// some code
但是我有错误InMemoryUploadedFile
。
我怎样才能将文件无误地发送到 cellery?
当您延迟任务时,Celery 将尝试序列化参数,在您的情况下,该参数包含一个文件。
无法序列化文件,尤其是内存中的文件。
因此,要解决此问题,您必须保存文件并将文件路径传递给延迟函数,然后在那里读取文件并进行计算。
Celery 不知道如何序列化文件对象等复杂对象。但是,这可以很容易地解决。我所做的是 encode/decode 将文件转换为其 Base64 字符串表示形式。这允许我直接通过 Celery 发送文件。
以下示例展示了如何(我有意将每个转换分开放置,尽管这可以以更 pythonic 的方式安排):
import base64
import tempfile
# (Django, HTTP server)
file = request.FILES['files'].file
file_bytes = file.read()
file_bytes_base64 = base64.b64encode(file_bytes)
file_bytes_base64_str = file_bytes_base64.decode('utf-8') # this is a str
# (...send string through Celery...)
# (Celery worker task)
file_bytes_base64 = file_bytes_base64_str.encode('utf-8')
file_bytes = base64.b64decode(file_bytes_base64)
# Write the file to a temporary location, deletion is guaranteed
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_file = os.path.join(tmp_dir, 'something.zip')
with open(tmp_file, 'wb') as f:
f.write(file_bytes)
# Process the file
这对于大文件来说效率不高,但对于 small/medium 大小的临时文件来说非常方便。