如果Azure存储中不存在Blob容器,则创建它。

14

我正在尝试使用Python在Azure Storage中创建blob容器。 我正在使用由MSDN提供的文档将Azure Blob存储集成到我的Python程序中。

以下是代码:

connectStr = <connString>
blobServiceClient = BlobServiceClient.from_connection_string(connectStr)
containerName = "quickstart-azureStorage"
localFileName = "quickstart-1.txt"
blobClient = blobServiceClient.create_container(containerName)

create_container()第一次创建Blob容器,但第二次会给我错误。

如果Blob容器不存在,则我想创建它。如果存在,则使用现有的Blob容器。

我正在使用Azure存储库版本12.0.0,即azure-storage-blob==12.0.0

我知道我们可以使用以下代码检查该容器中是否存在Blob,但我没有找到任何用于创建容器本身的内容。

检查Blob是否存在:

blobClient = blobServiceClient.get_blob_client(container=containerName, blob=localFileName)
if blobClient:
    print("blob already exists")
else:
     print("blob not exists")

异常:

RequestId:<requestId>
Time:2019-12-04T06:59:03.1459600Z
ErrorCode:ContainerAlreadyExists
Error:None
6个回答

16
如果您正在使用版本号在12.8之前的 azure-storage-blob,一个可能的解决方法是使用get_container_properties函数,如果容器不存在则会报错。

此解决方案测试于版本12.0.0

from azure.storage.blob import ContainerClient

container = ContainerClient.from_connection_string(connectStr, 'foo')

try:
    container_properties = container.get_container_properties()
    # Container foo exists. You can now use it.

except Exception as e:
    # Container foo does not exist. You can now create it.
    container.create_container()
如果您正在使用azure-storage-blob版本12.8之后的版本,则可以使用exist函数来检查容器是否存在。如果容器存在,该函数返回true,否则返回false。这个方案已经在12.8.1版本中测试过。
from azure.storage.blob import ContainerClient

container = ContainerClient.from_connection_string(connectStr, 'foo')

if container.exists():
    # Container foo exists. You can now use it.

else:
    # Container foo does not exist. You can now create it.
    container.create_container()

5
如果你查看 create_container 的文档,它说明:
创建一个指定账户下的新容器。如果已经存在同名容器,则操作失败。
克服这个问题的一种可能的解决方案是创建容器并捕获错误。如果容器已经存在,则会得到 Conflict (409) 错误代码。基于此,您可以确定容器是否存在。
如果降级 SDK 是一个选项,您可以使用 Python 存储 SDK 的 2.1 版本。那里的默认行为是如果容器存在则不抛出异常。您可以在这里查看 create_container 的代码: https://github.com/Azure/azure-storage-python/blob/master/azure-storage-blob/azure/storage/blob/baseblobservice.py

谢谢你的回答,Gaurav。我正在寻找类似于CreateIfNotExists()的函数(在C#中可用)https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.storage.blob.cloudblobcontainer.createifnotexists?view=azure-dotnet-legacy#Microsoft_Azure_Storage_Blob_CloudBlobContainer_CreateIfNotExists_Microsoft_Azure_Storage_Blob_BlobContainerPublicAccessType_Microsoft_Azure_Storage_Blob_BlobRequestOptions_Microsoft_Azure_Storage_OperationContext_ - Prasad Telkikar
你提供的建议是实现这个目标的另一种方式。如果 Python 库中没有包含 CrateIfNotExists() 这样的函数,那么我会尝试你的解决方案。 - Prasad Telkikar
我也很惊讶Python SDK没有CreateIfNotExists()方法的等效项。也许可以在Github存储库上提交一个问题? - Gaurav Mantri

2
如果您可以接受低版本的存储SDK,可以尝试使用azure-storage-blob==2.1.0,其中有一个exists方法来检查Blob或容器是否存在。如果存在,则返回true,否则返回false。
exists方法之后,如果返回false,则创建容器;如果返回true,则直接使用容器。
请参考下方图片:

enter image description here


1
这个 exist() 方法在 azure-storage-blob==12.0.0 中可用吗?我正在使用 azure-storage-blob12.0.0 版本。 - Prasad Telkikar
1
这个方法在最新的SDK中已经被移除了。如果你想使用最新的SDK,你必须使用Gaurav Mantri的方式来捕获异常代码。 - George Chen
@Prasad Telkikar,如果您不想使用这些方法,也许您可以使用 list_containers,然后在 for 循环中进行判断。 - George Chen
今天我将尝试使用 list_containers 方法,并在循环中进行检查。 - Prasad Telkikar
你现在应该知道最新的SDK不支持Python这种方法,那么你只需要决定是否可以使用旧的SDK。如果不能,就尝试我提到的其他方法,并选择一个更可接受的方案。 - George Chen

2
我们不再需要为此降级sdk。在azure-storage-blob的12.8.*版本中,我们现在拥有一个存在方法,该方法可用于 ContainerClient 对象。参考 [GitHub PR]
from azure.storage.blob import ContainerClient

# if you prefer async, use below import and prefix async/await as approp. 
# Code remains as is.
# from azure.storage.blob.aio import ContainerClient


def CreateBlobAndContainerIfNeeded(connection_string: str, container_name: str, 
                                   blob_name: str, blob_data):

    container_client = ContainerClient.from_connection_string(
        connection_string, container_name)

    if not container_client.exists():
        container_client.create_container()

    container_client.upload_blob(blob_name, blob_data)


if __name__ == "__main__":
    connection_string = "DefaultEndpointsProtocol=xxxxxxxxxxxxxxx"
    
    CreateBlobAndContainerIfNeeded(
        connection_string,
        "my_container",
        "my_blob_name.dat",
        "Hello Blob",
    )

1

@Paolo's 出色的回答类似,您可以在一个try..catch块中包装代码,并在容器资源已经存在时捕获azure.core.exceptions.ResourceExistsError 异常。

不同之处在于我捕获了特定引发的异常,而@Paolo's的答案则捕获了Exception,它是所有异常的基类。在这种情况下,我觉得捕获特定的异常更清晰,因为可以更明确地处理我要处理的错误。

此外,如果容器不存在,则 azure.storage.blob.BlobServiceClient.create_container 将创建容器资源。
from azure.core.exceptions import ResourceExistsError

blob_service_client = BlobServiceClient.from_connection_string(connection_string)

try:
    # Attempt to create container
    blob_service_client.create_container(container_name)

# Catch exception and print error
except ResourceExistsError as error:
    print(error)

# Do something with container

哪个异常会打印出这个错误:

The specified container already exists.
RequestId:5b70c1d8-701e-0028-3397-3c77d8000000
Time:2020-06-07T06:46:15.1526773Z
ErrorCode:ContainerAlreadyExists
Error:Non

我们也可以使用 pass语句 完全忽略异常:

try:
    # Attempt to create container
    blob_service_client.create_container(container_name)

# Catch exception and ignore it completely
except ResourceExistsError:
    pass

0

修改Paola的答案和Azure Storage Python SDK教程

connect_str = os.getenv('AZURE_STORAGE_CONNECTION_STRING')

# Create the BlobServiceClient object which will be used to create a container client
blob_service_client = BlobServiceClient.from_connection_string(connect_str)

# Create a unique name for the container
container_name = "foo"

# Create the container
try:
    container_client = blob_service_client.get_container_client(container_name)
    # Container foo exists. You can now use it.
except Exception as e:
    # Container foo does not exist. You can now create it.
    print(e)
    container_client = blob_service_client.create_container(container_name)

模块版本

Name: azure-storage-blob
Version: 12.5.0

参考资料:

Azure 存储 Python SDK

示例代码


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接