我们可以使用 boto3 Python 在 aws s3 存储桶之间递归复制文件和文件夹吗?

Posted

技术标签:

【中文标题】我们可以使用 boto3 Python 在 aws s3 存储桶之间递归复制文件和文件夹吗?【英文标题】:Can we copy the files and folders recursively between aws s3 buckets using boto3 Python? 【发布时间】:2017-09-13 10:56:53 【问题描述】:

是否可以使用boto3将一个源存储桶中的所有文件复制到另一个目标存储桶。并且源存储桶没有常规的文件夹结构。

Source bucket: SRC
Source Path: A/B/C/D/E/F..
where in D folder it has some files,
E folder has some files

Target bucket: TGT
Target path: L/M/N/

我需要使用boto3将SRC存储桶上方的所有文件和文件夹从文件夹C复制到N文件夹下的TGT存储桶。

任何人都可以知道任何 API 或者我们是否需要编写新的 python 脚本来完成这项任务。

【问题讨论】:

aws cli 有一个您可以使用的sync 命令。据我所知,boto3 没有等价物。 正确..我们可以在 aws cli 中使用 sync 或 cp --recursive ..但我需要在 boto3 中。如果不是,我们是否需要编写自己的代码来实现这一点..我的理解正确吗? 一种方法是使用 Bucket.objects.all() 获取每个对象的迭代器并使用 s3transfer 复制它们。这是 objects.all() 或 filter() 示例:***.com/questions/36042968/… 【参考方案1】:

S3 存储对象,它不存储文件夹,即使 '/' 或 '\' 也是对象键名的一部分。您只需要操作键名并将数据复制过来。

import boto3
old_bucket_name = 'SRC'
old_prefix = 'A/B/C/'
new_bucket_name = 'TGT'
new_prefix = 'L/M/N/'
s3 = boto3.resource('s3')
old_bucket = s3.Bucket(old_bucket_name)
new_bucket = s3.Bucket(new_bucket_name)

for obj in old_bucket.objects.filter(Prefix=old_prefix):
    old_source =  'Bucket': old_bucket_name,
                   'Key': obj.key
    # replace the prefix
    new_key = obj.key.replace(old_prefix, new_prefix, 1)
    new_obj = new_bucket.Object(new_key)
    new_obj.copy(old_source)

zvikico 建议的定义new_key 的优化技术:

new_key = new_prefix + obj.key[len(old_prefix):]

【讨论】:

mootmoot 感谢您的回复。我在 python 中使用了拆分和子串逻辑。问题已解决 谢谢!最后一行的source 应该是old_source 吗? @CarlSmith :感谢您指出错误。代码已更新。 实际上,obj.key.replace(old_prefix, new_prefix) 是危险的,因为前缀可能不止一次被发现。这样做会更安全new_prefix + obj.key[len(old_prefix):] 您也可以保留一个dictold_source 实例并不断更新Key,而不是每次都重新构建它。

以上是关于我们可以使用 boto3 Python 在 aws s3 存储桶之间递归复制文件和文件夹吗?的主要内容,如果未能解决你的问题,请参考以下文章

Python使用boto3操作AWS S3中踩过的坑

使用boto3 Python SDK返回AWS EC2可用性区域属性

如何:Zeppelin + boto3 + AWS 凭证

S3 AWS 的 IAM 角色和密钥设置使用 boto3 访问两个不同的账户存储桶

AWS RDS极光 - 通过boto3或aws cli创建跨区域读取副本

Boto3 AWS KMS 加密解密文件