当前位置: 首页 > 知识库问答 >
问题:

有没有一种简单的方法可以通过boto3重命名s3文件夹?

麹高义
2023-03-14

我有一个带文件夹的s3 bucket,文件夹里有大文件。

我想用python3-boto3脚本重命名文件夹。

我读了这个(《如何用Python重命名亚马逊S3文件夹对象》),他正在做的是复制带有新前缀的文件,然后删除原始文件夹。

这是非常不高效的方法,因为我有大文件,所以需要很长时间才能完成。

有没有更简单/更有效的方法

共有2个答案

贺亦
2023-03-14

很简单,不,很不幸。

s3中的文件夹结构有很多“问题”,看起来存储是平的。

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

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

或多或少,我会在重命名的目录中找到所有文件夹,然后使用boto3将它们放在新位置,然后使用aws 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])}"))

祁高格
2023-03-14

没有办法重命名s3对象/文件夹-您需要将它们复制到新名称,并不幸地删除旧名称。

aws cli中有一个mv命令,但它在幕后为您执行复制然后删除操作——因此您可以简化操作,但它不是真正的“重命名”。

https://docs.aws.amazon.com/cli/latest/reference/s3/mv.html

 类似资料:
  • 简而言之:有没有一种方法可以在gcc或CLANG中不推荐命名空间? 长: 现在我想知道是否有更好的方法来做类似的事情,比如将名称空间util的使用标记为不推荐使用。 我们使用GCC4.7.3作为生产编译器,但是针对clang进行构建和测试,以尝试捕捉gcc的细节;因此,在这些编译器上工作的东西会有所帮助。

  • 问题内容: 我正在建立一个带有flask的网站,其中用户具有帐户并能够登录。我正在使用flask-principal作为登录部分和角色管理。有没有办法让用户的会话在5分钟或10分钟后过期?我在flask文档或flask-principal文档中找不到该文件。 我想到了一种手动方法,在登录时在服务器端设置一个带有时间标签的变量,并在用户执行下一个操作时,服务器会验证该时间戳记上的时间增量并删除会话。

  • 问题内容: 我正在建立一个带有flask的网站,其中用户具有帐户并能够登录。我正在使用flask- principal作为登录部分和角色管理。有没有办法让用户的会话在5分钟或10分钟后过期?我在flask文档或flask- principal文档中找不到该文件。 我想到了一种手动方法,在登录时在服务器端设置一个带有时间标签的变量,并在用户执行下一个操作时,服务器会验证该时间戳记上的时间增量并删除会

  • 问题内容: 我正在研究Java应用程序的一部分,该应用程序将图像作为字节数组,将其读入实例,然后将其传递给第三方库进行处理。 对于单元测试,我想获取一个图像(从磁盘上的文件中获取),并断言它等于代码处理过的同一图像。 我的 预期 是使用从磁盘上的PNG文件读取的。 我的 测试 代码将相同的文件读入A,并将其作为PNG写入字节数组,以提供给被测系统。 当被测系统将字节数组写入新数组时,我想断言这两个

  • 问题内容: 现在我正在做: 有没有更有效的方法直接从Find(或其他搜索功能)中获取带有用户名的slice,而没有struct和range循环? 问题答案: MongoDB的结果始终是文档列表。因此,如果要获取值列表,则必须像以前一样手动将其转换。 使用自定义类型(源自) 另外请注意,如果您要创建自己的类型(从派生),则可以覆盖其取消编组逻辑,并仅从文档中“提取” 。 它看起来像这样: 然后将用户

  • 在Borland VCL库中,几乎所有控件都有提示属性。在运行时,当您将鼠标放在相应的控件上时,当您移动鼠标时,一个带有提示文本的小框会弹出并再次消失,例如Windows资源管理器和其他程序中的帮助消息,当鼠标光标放在按钮上时。 JavaFX中是否有类似的概念(实际上,我使用的是ScalaFX)? 当然,我可以创建一个没有装饰的新舞台,添加一些鼠标监听器等,但是它不是已经在某个地方可用了吗?