【问题标题】:Dynamic rename Azure Blob if already uploaded如果已上传,则动态重命名 Azure Blob
【发布时间】:2020-03-14 05:26:39
【问题描述】:

我有一组文件(未本地保存)需要上传到 azure blob 存储并每天更新。

(1) 有一定数量的同名文件(内容不同)应保存为单独的 blob。
(2) 更新的文件集应覆盖相应的前一天 blob。

有没有办法检查 blob 是否已经存在并通过附加一个数字来动态重命名它(因为 (2) 不能附加时间戳)?

我正在使用以下函数上传我的所有文件:

def azure_upload_file(block_blob_service, container, local_file_path, local_file_name):
    logger = logging.getLogger('data')

    isExist = block_blob_service.exists(container, local_file_name)

    blobname = os.path.splitext(local_file_name)[0]
    blobext =  os.path.splitext(local_file_name)[1]


    if isExist is True:
        blob_file_name = '{}_{}{}'.format(blobname, '#', blobext)
    else:
        blob_file_name = local_file_name
    full_path_to_file =os.path.join(local_file_path, local_file_name)

    blob = block_blob_service.create_blob_from_path(container, blob_file_name, full_path_to_file)
    blob_url = block_blob_service.make_blob_url(container, blob_file_name)

    logger.info('Uploaded file {} to azure blob storage'.format(blob_file_name))
    os.unlink(full_path_to_file)

    return blob_url

例子:

日期:2019 年 19 月 11 日 - 首次上传

filename.ext -> blob
1. abcd.zip -> abcd.zip
2. abcd.zip -> abcd(1).zip
3. abcd.zip -> abcd(2).zip
4. defg.csv -> defg.csv

等等..

我想要的只是以某种方式智能地填充代码中的“#”,这样每当我拥有更新的文件集时,我就已经知道应该将文件覆盖到哪个 blob。

即,如果我在 2019 年 11 月 20 日有一组新文件

例子:

日期:20-11-2019 - 第二次上传

新文件名.ext -> blob
1. abcd.zip -> abcd.zip
2. abcd.zip -> abcd(1).zip
3. abcd.zip -> abcd(2).zip
4. defg.csv -> defg.csv

等等..

我已经浏览过类似的文章:
1.Azure blob upload rename if blob name exist
2.Faster Azure blob name search with python?

它们都不能解决我的问题。想知道是否有一种有效且简单的方法可以实现这一目标?

【问题讨论】:

  • 我的理解是这样的: 1. 首先,您尝试上传一个 blob,如果它已经存在,然后根据上传 bob 的时间决定是要覆盖它还是复制它? 2. 如果 blob 是在今天之前上传的,则覆盖它,否则将 (1) 添加到名称中并上传新的 blob 让我知道这是否不是您要执行的操作
  • @rakshith1124 不完全是。 (1) 我想将一组文件(其中一些具有完全相同的名称)上传到 azure blob 存储。 (2) 这组文件每天都有新版本。所以,一旦我得到这些新版本,我应该为它们中的每一个覆盖已经存在的 blob。
  • 你有没有试过的代码?

标签: python azure azure-blob-storage


【解决方案1】:

如果您考虑拥有同一个文件的多个版本,您只需在 blob 的名称上附加一个时间戳:

  • abcd20191118131800.zip
  • abcd20191118131900.zip

按文件名排序(升序/降序)将为您提供最新/最旧的文件

【讨论】:

  • 嗨@Thiago,我已经编辑了我的问题。请看一下。
【解决方案2】:

您可以使用exists 方法检查blob是否已经存在,然后检查文件名是否需要更改。

以下是我的测试代码,它可以为我工作。

    block_blob_service = BlockBlobService(account_name=accountName, account_key=accountKey,
                                              socket_timeout=10000)

    container_name ="test"
    local_path = "./data"
    local_file_name = "quickstart.txt"

    isExist = block_blob_service.exists(container_name, local_file_name)

if isExist:
    local_file_name = local_file_name.replace('.txt', '1.txt')
    upload_file_path = os.path.join(local_path, local_file_name)
    print("\nUploading to Azure Storage as blob:\n\t" + local_file_name)
    # Upload the created file, use local_file_name for the blob name.
    block_blob_service.create_blob_from_path(
    container_name, local_file_name, upload_file_path)
else:
    upload_file_path = os.path.join(local_path, local_file_name)
    print("\nUploading to Azure Storage as blob:\n\t" + local_file_name)
    block_blob_service.create_blob_from_path(
container_name, local_file_name, upload_file_path)

更新

    container_name ="test"
    local_path = "./data"
    local_file_name="quickstart.txt"


    isExist = block_blob_service.exists(container_name, local_file_name)

    if not(isExist):
        upload_file_path = os.path.join(local_path, local_file_name)
        print("\nUploading to Azure Storage as blob:\n\t" + local_file_name)
        block_blob_service.create_blob_from_path(container_name, local_file_name, upload_file_path)
    else:
        i=1
        while(isExist):
            name = local_file_name.split('.')[0] + '(' + str(i) + ').' + local_file_name.split('.')[1]
            isExist = block_blob_service.exists(container_name, name)
            i=i+1
        upload_file_path = os.path.join(local_path, local_file_name)
        print("\nUploading to Azure Storage as blob:\n\t" + name)
        block_blob_service.create_blob_from_path(container_name, name, upload_file_path)

【讨论】:

  • 我有两个以上同名的文件。我不能总是附加 (1)。
  • @Saketh Gangam ,我已经更新了我的代码,而 isExist 是 true 判断文件名可以保存。
  • @Saketh Gangam,有关于这个问题的更新吗?你能用我的代码实现它吗?
  • 我有超过 7000 个文件,检查是否存在同名的 blob 然后重命名它们的计算成本很高。
  • @Saketh Gangam,如果您不想检查 blob 的存在,您更喜欢哪种方式?请做更多描述,因为 Azure 存储没有自动完成这项工作的方法。或者你可以在你的文件名中添加一个时间戳,这样会非常容易实现和高效。
【解决方案3】:

我不能完全理解你的问题,但据我了解,这是你想要使用最新版本的 azure-storage-blob (v12) 做的事情

如果你想在 blob 已经存在的情况下重命名 blob:

from azure.storage.blob import ContainerClient
from azure.core.exceptions import ResourceExistsError

blob_name = "abcd.zip"
container_client = ContainerClient.from_connection_string(conn_str, "container_name")
try:
    blob_client = container_client .get_blob_client(blob_name)
    # upload the blob if it doesn't exist
    blob_client.upload_blob(data)
except ResourceExistsError:
    # check the number of blobs with the same prefix.
    # For example, This will return a generator of [abcd, abcd(1), abcd(2)]
    blobs = list(container_client.list_blobs(name_starts_with=blob_name))
    length = len(blobs)
    if length == 1:
        # it means there is only one blob - which is from the previous version
        blob_client.upload_blob(data, overwrite=True)
    else:
        # if there are 10 files with the name starting with abcd, it means your name for the 11th file will be abcd(10).
        name = blob_name.split('.')[0] + '(' + str(length) + ').' + a.split('.')[1]
        blob_client = container_client .get_blob_client(blob_name)
        blob_client.upload_blob(data)

这是你想要做的吗?如果这不能解决问题,请告诉我。

【讨论】:

  • 我有两个以上同名的文件。我不能总是附加 (1)。
  • 稍微更新了代码。如果您有一些现有的代码,请在此处发布。会更容易看出哪里出了问题。
  • 我已经编辑了问题并添加了代码。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
  • 2017-02-20
  • 2014-07-20
  • 2012-04-02
  • 2013-09-29
相关资源
最近更新 更多