【问题标题】:How to rename the s3 file name by using python boto3如何使用 python boto3 重命名 s3 文件名
【发布时间】:2021-10-16 03:37:14
【问题描述】:

您好,我在 s3 存储桶中创建了一个新文件/文件夹,现在我想更改文件夹/文件名的名称。 如何使用 python boto3 重命名 s3 存储桶中的文件/文件夹名称

【问题讨论】:

  • 没有直接的 boto3 api 来重命名 s3 对象。您可以参考这些现有解决方案来实现此用例。 reference 1reference 2

标签: python python-3.x amazon-web-services amazon-s3 boto3


【解决方案1】:

Amazon S3 中没有“重命名”功能。对象名称是不可变的。

您需要:

  • 将对象复制到新密钥(文件名)
  • 删除原始对象

请注意,文件夹实际上并不存在于 Amazon S3 中。相反,对象的完整路径存储在其 Key 中。因此,无法重命名文件夹,因为这将涉及重命名该路径中的所有对象。 (而且对象不能重命名,如上所述。)

如果您想“重命名文件夹”,您可以编写一个 Python 脚本:

  • 获取给定前缀内所有对象的列表
  • 遍历每个对象,然后:
  • 将对象复制到新键
  • 删除原始对象

如果您不想编写此代码,那么有一些工具(例如 Cyber​​duck)可以提供良好的用户界面,并且可以为您完成许多此类操作。

【讨论】:

    【解决方案2】:

    s3 中的文件夹结构存在很多“问题”,因为存储空间是扁平的。

    我有一个 Django 项目,我需要能够重命名文件夹但仍保持目录结构完整,这意味着空文件夹也需要复制并存储在重命名的目录中。

    aws cli 很棒,但 cpsyncmv 都没有将空文件夹(即以“/”结尾的文件)复制到新文件夹位置,所以我混合使用了 boto3aws cli 完成任务。

    我或多或少找到重命名目录中的所有文件夹,然后使用boto3将它们放在新位置,然后我cpaws cli的数据,最后将其删除。

    import threading
    
    import os
    from django.conf import settings
    from django.contrib import messages
    from django.core.files.storage import default_storage
    from django.shortcuts import redirect
    from django.urls import reverse
    
    def rename_folder(request, client_url):
        """
        :param request:
        :param client_url:
        :return:
        """
        current_property = request.session.get('property')
        if request.POST:
            # name the change
            new_name = request.POST['name']
            # old full path with www.[].com?
            old_path = request.POST['old_path']
            # remove the query string
            old_path = ''.join(old_path.split('?')[0])
            # remove the .com prefix item so we have the path in the storage
            old_path = ''.join(old_path.split('.com/')[-1])
            # remove empty values, this will happen at end due to these being folders
            old_path_list = [x for x in old_path.split('/') if x != '']
    
            # remove the last folder element with split()
            base_path = '/'.join(old_path_list[:-1])
            # # now build the new path
            new_path = base_path + f'/{new_name}/'
            # remove empty variables
            # print(old_path_list[:-1], old_path.split('/'), old_path, base_path, new_path)
            endpoint = settings.AWS_S3_ENDPOINT_URL
            # # recursively add the files
            copy_command = f"aws s3 --endpoint={endpoint} cp s3://{old_path} s3://{new_path} --recursive"
            remove_command = f"aws s3 --endpoint={endpoint} rm s3://{old_path} --recursive"
            
            # get_creds() is nothing special it simply returns the elements needed via boto3
            client, resource, bucket, resource_bucket = get_creds()
            path_viewing = f'{"/".join(old_path.split("/")[1:])}'
            directory_content = default_storage.listdir(path_viewing)
    
            # loop over folders and add them by default, aws cli does not copy empty ones
            # so this is used to accommodate
            folders, files = directory_content
            for folder in folders:
                new_key = new_path+folder+'/'
                # we must remove bucket name for this to work
                new_key = new_key.split(f"{bucket}/")[-1]
                # push this to new thread
                threading.Thread(target=put_object, args=(client, bucket, new_key,)).start()
                print(f'{new_key} added')
    
            # # run command, which will copy all data
            os.system(copy_command)
            print('Copy Done...')
            os.system(remove_command)
            print('Remove Done...')
    
            # print(bucket)
            print(f'Folder renamed.')
            messages.success(request, f'Folder Renamed to: {new_name}')
    
        return redirect(request.META.get('HTTP_REFERER', f"{reverse('home', args=[client_url])}"))
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-06
      • 2013-08-24
      • 2011-01-30
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 2022-10-14
      • 2020-06-05
      相关资源
      最近更新 更多