【问题标题】:Save .xlsx file to Azure blob storage将 .xlsx 文件保存到 Azure Blob 存储
【发布时间】:2021-09-20 20:54:51
【问题描述】:

我有一个 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 种情况下 - 1)您的帐户密钥不正确(Duh!,但确实发生了)和 2)运行代码的机器上的时间已关闭。你能检查一下它们是否都正确吗?
  • 现在我很困惑:)。您在代码中的哪个位置收到此错误?您能否编辑您的问题并提供该信息。

标签: python django azure azure-blob-storage


【解决方案1】:

您是否尝试过如下方式:

# 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

【讨论】:

  • 感谢您的回答。我认为我不能利用本地临时文件,因为我的部署在 Azure 应用服务中。我将编辑我原来的问题,说我需要处理内存中的文件。
  • 在这种情况下,您必须创建一个临时文件,该文件将存储在应用服务内存中。
【解决方案2】:

由于我不完全理解的原因(欢迎 cmets 解释!),我可以成功地将 .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'))

【讨论】:

    猜你喜欢
    • 2020-08-25
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2020-07-13
    • 2020-02-11
    • 1970-01-01
    • 2017-08-18
    • 2021-12-08
    相关资源
    最近更新 更多