如何使用 blockblobservice 的 delete_blob 方法删除 azure 容器内的文件夹(blob)?

Posted

技术标签:

【中文标题】如何使用 blockblobservice 的 delete_blob 方法删除 azure 容器内的文件夹(blob)?【英文标题】:How do i delete a folder(blob) inside an azure container using delete_blob method of blockblobservice? 【发布时间】:2018-08-29 10:54:47 【问题描述】:

delete_blob() 似乎只删除容器内的文件以及容器内的文件夹和子文件夹。但是我在尝试从容器中删除文件夹时在 python 中看到以下错误。

Client-Request-ID=7950669c-2c4a-11e8-88e7-00155dbf7128 重试策略不允许重试:Server-Timestamp=Tue, 20 Mar 2018 14:25:00 GMT, Server-Request-ID=54d1a5d6 -b01e-007b-5e57-c08528000000, HTTP状态码=404, Exception=指定的blob不存在。ErrorCode: BlobNotFoundBlobNotFound指定的blob不存在。RequestId:54d1a5d6-b01e-007b-5e57-c08528000000时间:2018 -03-20T14:25:01.2130063Z.

azure.common.AzureMissingResourceHttpError:指定的 blob 不存在。错误代码:BlobNotFound BlobNotFound指定的 blob 不存在。 请求ID:54d1a5d6-b01e-007b-5e57-c08528000000 时间:2018-03-20T14:25:01.2130063Z

有人可以帮忙吗?

【问题讨论】:

【参考方案1】:

在 Azure Blob 存储中,这样的文件夹不存在。它只是 blob 名称的前缀。例如,如果您看到一个名为 images 的文件夹,并且它包含一个名为 myfile.png 的 blob,则该 blob 的名称本质上是 images/myfile.png。因为文件夹并不真正存在(它们是虚拟的),所以不能直接删除文件夹。

您需要做的是单独删除该文件夹中的所有 blob(或者换句话说,删除名称以该虚拟文件夹名称/路径开头的 blob。删除所有 blob 后,该文件夹会自动消失。

为了完成此操作,首先您需要获取名称以虚拟文件夹路径开头的所有 blob。为此,您将使用list_blobs 方法并在prefix 参数中指定虚拟文件夹路径。这将为您提供以该前缀开头的 blob 列表。获得该列表后,您将一一删除 Blob。

【讨论】:

非常感谢高拉夫!你的方法很有帮助:) 还有 Gaurav,我如何确定 blob 是文件还是虚拟文件夹? blob.name 为我们提供了名称。同样,是否有任何参数告诉我们它是文件还是虚拟文件夹? 如果您查看列表结果,我相信虚拟文件夹的类型为“BlobPrefix”。如果项目是文件夹或 blob,这应该是一个很好的指标。否则,您可以检查属性是否存在。对于虚拟文件夹,您不应取回任何属性。 还有一件事....如果您只想列出容器/虚拟文件夹中的 blob 而不是虚拟文件夹,请将 delimiter 指定为空字符串。这将只返回一个 blob 列表。 HTH。 Gaurav,我正在尝试使用以下代码将 blob 下载到本地文件系统: generator = session.list_blobs(container_name,path_to_file+'/',delimiter='/') for blob in generator : bl = os.path.basename(blob.name) session.get_blob_to_path(container_name,bl,bl) 只有第一个 blob 被下载但我有 azure.common.AzureMissingResourceHttpError 并且它说指定的 blob 不存在。因此,我无法下载其余部分。你能建议如何摆脱这个错误吗?【参考方案2】:

这个过程有两点需要理解,你可以使用 delete_blob 删除特定的文件、文件夹、图像...(blob),但是如果你想删除 containers,您必须使用 delete_container 来删除其中的所有 blob,这是我创建的一个示例,用于删除路径/虚拟文件夹中的 blob:

from azure.storage.blob import BlockBlobService

block_blob_service = BlockBlobService(account_name='yraccountname', account_key='accountkey')
print("Retreiving blobs in specified container...")
blob_list=[]
container="containername"
def list_blobs(container):
        try:

                global blob_list
                content = block_blob_service.list_blobs(container)
                print("******Blobs currently in the container:**********")
                for blob in content:
                        blob_list.append(blob.name)
                        print(blob.name)
        except:
                print("The specified container does not exist, Please check the container name or if it exists.")
list_blobs(container)
print("The list() is:")
print(blob_list)
print("Delete this blob: ",blob_list[1])
#DELETE A SPECIFIC BLOB FROM THE CONTAINER
block_blob_service.delete_blob(container,blob_list[1],snapshot=None)
list_blobs(container)

请参考我的仓库中的代码以及自述文件部分的解释,以及新的存储脚本:https://github.com/adamsmith0016/Azure-storage

【讨论】:

感谢您的回答。 delete_container() 删除整个容器。但我只想删除该容器下的一个文件夹。有什么办法吗? 您应该使用 Delete_blob,使用以下语法:.delete_blob(container_name, 'myblob') 我会将其添加到答案中。 亚当,我一直在尝试同样的事情:b.delete_blob('29azurefs','one') 我得到以下异常:Client-Request-ID=eb93b964-2cc1-11e8- b3fd-00155dbf7128 重试策略不允许重试:Server-Timestamp=Wed,2018 年 3 月 21 日 04:40:02 GMT,Server-Request-ID=5e33d75b-701e-0083-3bce-c04e35000000,HTTP 状态码=404, Exception=指定的 blob 不存在。ErrorCode: BlobNotFoundBlobNotFound指定的 blob 不存在。 RequestId:5e33d75b-701e-0083-3bce-c04e35000000Time:2018-03-21T04:40:03.1598904Z 列出 blob 时是否可以看到它?除了 blob 名称之外,您可以将其他属性添加到 delete_blob 吗? 正如我提到的,使用 delete_blob(,),我只能删除文件。如果我为 blob 名称指定一个文件夹名称,那么它会返回一个异常。【参考方案3】:

对于在 python 中寻找解决方案的其他人。这对我有用。

首先创建一个变量来存储您要删除的文件夹中的所有文件。

然后对于该文件夹中的每个文件,通过说明容器的名称,然后是实际的 foldername.name 来删除文件。

通过删除文件夹中的所有文件,文件夹在 azure 中被删除。

def delete_folder(self, containername, foldername):
    folders = [blob for blob in blob_service.block_blob_service.list_blobs(containername) if blob.name.startswith(foldername)]
    if len(folders) > 0:
        for folder in folders:
            blob_service.block_blob_service.delete_blob(containername, foldername.name)
            print("deleted folder",folder name)

【讨论】:

.list_blobs(container_name, prefix=foldername) 会大大加快请求速度【参考方案4】:

您无法删除 Azure Blob 中的非空文件夹,但如果您先删除子文件夹中的文件,则可以实现此目的。以下解决方法将开始将其从文件中删除到父文件夹。

from azure.storage.blob import BlockBlobService
blob_client = BlockBlobService(account_name='', account_key='')
containername = 'XXX'
foldername = 'XXX'

def delete_folder(containername, foldername):
    folders = [blob.name for blob in blob_client.list_blobs(containername, prefix=foldername)]
    folders.sort(reverse=True, key=len)
    if len(folders) > 0:
        for folder in folders:
            blob_client.delete_blob(containername, folder)
            print("deleted folder",folder)

【讨论】:

【参考方案5】:

使用list_blobs(name_starts_with=folder_name)delete_blob()

完整代码:

blob_service_client = BlobServiceClient.from_connection_string(conn_str=CONN_STR)
blob_client = blob_service_client.get_container_client(AZURE_BLOBSTORE_CONTAINER)

for blob in blob_client.list_blobs(name_starts_with=FOLDER_NAME):
    blob_client.delete_blob(blob.name)

【讨论】:

以上是关于如何使用 blockblobservice 的 delete_blob 方法删除 azure 容器内的文件夹(blob)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中生成 Azure blob SAS URL?

如何使用 automake 安装 D 库的 .d 文件?

max()如何使用d.get?

如何使用 webpack 生成 d.ts 和 d.ts.map 文件?

如何使用 .d.ts 文件

如何在 MATLAB 中使用 2-D 掩码索引 3-D 矩阵?