将 .xlsx 文件保存到 Azure blob 存储

时间:2021-07-11 08:54:50

标签: python django azure azure-storage-blobs

我有一个 Django 应用程序和表单,它接受来自用户的 Excel(.xlsx) 和 CSV (.csv) 文件。我需要将这两个文件都保存到 Azure Blob 存储。我发现处理 .csv 文件很简单,但在尝试上传 xlsx 文件时相同的代码失败:

from azure.storage.blob import BlobServiceClient

# This code executes successfully when saving a CSV to blob storage
blob_service_client = BlobServiceClient.from_connection_string(os.getenv('STORAGE_CONN_STRING'))
blob_client = blob_service_client.get_blob_client(container="my-container-name", blob=form.cleaned_data.get('name_of_form_field_for_csv_file'))
blob_client.upload_blob(form.cleaned_data.get('name_of_form_field_for_csv_file''))


# This code fails when saving xlsx to blob storage

blob_client = blob_service_client.get_blob_client(container="my-container-name", blob=form.cleaned_data.get('name_of_form_field_for_xlsx_file'))
blob_client.upload_blob(form.cleaned_data.get('name_of_form_field_for_xlsx_file''))

ClientAuthenticationError at /mypage/create/
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

但是,我一直无法弄清楚如何保存 .xlsx 文件。我 - 也许有点天真 - 假设我可以按原样传递 .xlsx 文件(如上面的 .csv 示例),但我收到错误:

ClientAuthenticationError at /mypage/create/
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

我发现 this SO Answer 关于上述错误,但对于错误的含义完全没有共识,而且我无法从该链接进一步取得进展。但是,有一些关于将数据作为字节流发送到 Azure blob 存储的讨论。这是一种可能的前进方式吗?我应该在这里注意,理想情况下,当我的应用程序部署在应用服务中时,我需要处理内存中的文件(我的理解是我无权访问创建和操作文件的文件系统。)

我还了解到 .xlsx 文件是压缩的,所以我需要先解压缩文件,然后将其作为字节流发送吗?如果是这样,有没有人有这方面的经验,可以为我指明正确的方向?

存储帐户连接字符串:

STORAGE_CONN_STRING=DefaultEndpointsProtocol=https;AccountName=REDACTED;AccountKey=REDACTED;EndpointSuffix=core.windows.net

2 个答案:

答案 0 :(得分:0)

您是否尝试过以下操作:

# Create a local directory to hold blob data
    local_path = "./data"
    os.mkdir(local_path)

# Create a file in the local data directory to upload and download
    local_file_name = str(uuid.uuid4()) + ".xlsx"
    upload_file_path = os.path.join(local_path, local_file_name)

# Write text to the file

    file = open(upload_file_path, 'w')
    file.write("Hello, World!")
    file.close()

# Create a blob client using the local file name as the name for the blob
    blob_client = 
    blob_service_client.get_blob_client(container=container_name, 
    blob=local_file_name)

# Upload the created file
with open(upload_file_path, "rb") as data:
    blob_client.upload_blob(data)

https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-python

答案 1 :(得分:0)

由于我不完全理解的原因(欢迎评论解释!),我可以成功地将 .xlsx 文件保存到 Azure Blob 存储:

self.request.FILES['name_of_form_field_for_xlsx_file']

我怀疑 Django 中 request.FILESform.cleaned_data.get() 之间处理 csv 和 xlsx 文件的方式有所不同,导致按照原始问题出现身份验证错误。

保存 .csv 和 .xlsx 的完整代码是(注意这是在 FormView 内):

from azure.storage.blob import BlobServiceClient

# Set connection string
blob_service_client = BlobServiceClient.from_connection_string(os.getenv('STORAGE_CONN_STRING'))

# Upload an xlsx file
blob_client = blob_service_client.get_blob_client(container="my-container", blob=self.request.FILES['xlsx_file'])
blob_client.upload_blob(self.request.FILES['xlsx_file'])

# Upload a CSV file
blob_client = blob_service_client.get_blob_client(container="my-container", blob=form.cleaned_data.get('csv_file'))
blob_client.upload_blob(form.cleaned_data.get('csv_file'))