0

我正在使用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)
4

3 回答 3

2

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

复制操作的源 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方法.

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 并跟踪您的偏移量和长度,直到用完所有块。

编辑2:

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?)
于 2019-11-19T18:22:52.287 回答
2

您无法在创建后立即更改 Blob 类型。请参阅从 URL REST API 复制 Blob,无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))

在此处输入图像描述

于 2019-11-19T07:06:34.613 回答
0

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

于 2019-11-19T02:23:47.063 回答