从远程URL将Azure Blob复制为BlockBlob

我正在使用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)
yumikooo 回答:从远程URL将Azure Blob复制为BlockBlob

创建后无法立即更改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,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))

enter image description here

,

这是您要使用最新版本(v12)执行的操作 根据{{​​3}},

  

复制操作的源Blob可能是块Blob,附加Blob,           或页面Blob。如果目标Blob已经存在,则它必须是           与源Blob相同。

现在,您不能使用start_copy_from_url来指定Blob类型。但是,在某些情况下,您可以使用同步复制APIS来做到这一点。

例如,对于块到页面Blob,首先创建目标页面Blob,然后在目标上调用update_range_from_url,每个块都从源中提取4 MB。

类似地,在您的情况下,请先创建一个空的块blob,然后使用to the documentation

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?)
,

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

本文链接:https://www.f2er.com/3076837.html

大家都在问