【问题标题】:Copy Azure Blob as BlockBlob from Remote URL从远程 URL 将 Azure Blob 复制为 BlockBlob
【发布时间】:2020-03-14 11:14:18
【问题描述】:

我正在使用 azure-sdk-for-python BlobClient start_copy_from_url 将远程文件复制到我的本地存储。

但是,该文件始终以 AppendBlob 而不是 BlockBlob 的形式结束。我看不出如何强制目标 BlockType 为 BlockBlob。

connection_string = "connection string to my dest blob storage account"
container_name = "myContainerName"
dest_file_name = "myDestFile.csv"
remote_blob_url = "http://path/to/remote/blobfile.csv"

client = BlobServiceClient.from_connection_string(connection_string)
dest_blob = client.get_blob_client(container_name, dest_file_name)
dest_blob.start_copy_from_url(remote_blob_url)

【问题讨论】:

    标签: python azure azure-blob-storage azure-sdk-python


    【解决方案1】:

    您无法在创建后立即更改 Blob 类型。请参阅 Copy Blob From URL REST API,没有 blob-types 标头。

    您可以参考我的代码从附加 blob 创建块 blob:

    from azure.storage.blob import BlobPermissions
    from datetime import datetime, timedelta
    from azure.storage.blob import BlockBlobService
    import requests
    from io import BytesIO
    
    account_name = "***"
    account_key = "***"
    container_name = "test"
    blob_name = "test2.csv"
    
    block_blob_service = BlockBlobService(account_name, account_key)
    
    sas_token = block_blob_service.generate_blob_shared_access_signature(container_name, blob_name,
                                                                         permission=BlobPermissions.READ,
                                                                         expiry=datetime.utcnow() + timedelta(hours=1))
    blob_url_with_sas = block_blob_service.make_blob_url(container_name, blob_name, sas_token=sas_token)
    
    r = requests.get(blob_url_with_sas, stream=True)
    block_blob_service.create_blob_from_stream("test", "jay.block", stream=BytesIO(r.content))
    

    【讨论】:

      【解决方案2】:

      这是您想要使用最新版本 (v12) 执行的操作 根据to the documentation

      复制操作的源 blob 可以是块 blob、附加 blob、 或页面blob。如果目标 blob 已经存在,它必须是 与源 blob 相同的 blob 类型。

      目前,您不能使用 start_copy_from_url 指定 blob 类型。但是,在某些情况下,您可以使用同步复制 APIS 来执行此操作。

      例如,对于块到页 Blob,首先创建目标页 Blob,然后在目标上调用 update_range_from_url,每个块来自源 4 MB。

      同样,在您的情况下,首先创建一个空块 blob,然后使用 stage_block_from_url method

      from azure.storage.blob import ContainerClient
      import os
      
      conn_str = os.getenv("AZURE_STORAGE_CONNECTION_STRING")
      dest_blob_name = "mynewblob"
      source_url = "http://www.gutenberg.org/files/59466/59466-0.txt"
      
      container_client = ContainerClient.from_connection_string(conn_str, "testcontainer")
      
      blob_client = container_client.get_blob_client(dest_blob_name)
      # upload the empty block blob
      blob_client.upload_blob(b'')
      
      # this will only stage your block
      blob_client.stage_block_from_url(block_id=1, source_url=source_url)
      # now it is committed
      blob_client.commit_block_list(['1'])
      
      # if you want to verify it's committed now
      committed, uncommitted = blob_client.get_block_list('all')
      assert len(committed) == 1
      

      如果这不起作用,请告诉我。

      编辑: 您可以利用source_offsetsource_length 参数分块上传块。 例如,

      stage_block_from_url(block_id, source_url, source_offset=0, source_length=10)

      将上传前 10 个字节,即从 0 到 9 的字节。 因此,您可以使用计数器来不断增加 block_id 并跟踪您的偏移量和长度,直到用完所有块。

      EDIT2:

      for step in range(....):
          ###
          blob.stage_block_from_url(...)
          ##do not commit it##
      #outside the for loop
      blob.commit_block_list([j for j in range(i+1)]) (#or i+2?)
      

      【讨论】:

      • 我收到错误:复制源的源请求正文太大,超过了最大允许限制 (100MB)。仅供参考,文件为 1.3GB
      • 您是否尝试使用 4 mb 块暂存块?让我检查一下。
      • docs.microsoft.com/en-us/rest/api/storageservices/… Put Block From URL 上传块以供将来包含在块 blob 中。一个块 blob 最多可以包含 50,000 个块。每个块可以有不同的大小,最大为 100 MB。因此,块 blob 的最大大小略大于 4.75 TB(100 MB X 50,000 个块)。这意味着,如果您使用任何同步复制 APIS,则必须以 100 mb 的块上传您的 blob
      • 看看编辑
      • 我创建了一个循环来迭代块。我在某个地方有一个错误。它显示所有 1.3 GB 的上传,但最终只有 4.8 MB 存储。
      【解决方案3】:

      据我所知,blob 类型之间没有直接转换。为此,您需要下载 Blob 并将其重新上传为 Block Blob。

      【讨论】:

        猜你喜欢
        • 2019-08-18
        • 2013-12-23
        • 2020-08-03
        • 1970-01-01
        • 2014-04-13
        • 2021-06-16
        • 2015-01-16
        • 2020-08-18
        • 1970-01-01
        相关资源
        最近更新 更多