Boto3/S3:使用copy_object重命名对象

101

我正在尝试使用Python boto3重命名S3存储桶中的文件,但我无法清楚地理解参数。有人可以帮我吗?

我的计划是将对象复制到一个新对象,然后删除实际对象。

我在这里找到了类似的问题,但我需要使用boto3进行解决方案。

3个回答

165

我找到了另一个解决方案

s3 = boto3.resource('s3')
s3.Object('my_bucket','new_file_key').copy_from(CopySource='my_bucket/old_file_key')
s3.Object('my_bucket','old_file_key').delete()

34
谢谢你提供的这个解决方案。如果其他人有和我一样的问题,这里有一个提示。在第一次阅读时,我错过了传递给CopySource的密钥包括存储桶名称这一点。这很酷,因为这意味着您可以在不同的存储桶之间复制,但是我被困扰了,因为我只是尝试更改同一存储桶中的密钥,并且没有想到加上存储桶名称。当我这样做后,我遇到了权限错误而不是更合理的NoSuchBucket错误。这使我更加困惑!希望现在大家都能避免这种错误。 - t1m0
5
为了复制对象,我使用了字典格式的CopySource(字符串格式对我不起作用):CopySource='string' or {'Bucket': 'string', 'Key': 'string', 'VersionId': 'string'}。更多信息请查看http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.copy_object。 - Kurtis
4
对象在复制之前是否被删除了?我们如何确保最后两个语句的顺序? - Randy Tang
唯一的问题是,如果您将事件附加到存储桶,则它会再次触发这些事件。 - Sławomir Lenart
如果您只想移动文件(真正改变指针位置),那么这不是很低效吗?因为这里我们必须实际复制字节。难道没有一种方法可以仅更改引用(即传统的mv操作)吗? - hurlbz
显示剩余2条评论

74

在S3中,无法重命名对象,因此您需要将其复制到新名称,然后删除旧对象:

client.copy_object(Bucket="BucketName", CopySource="BucketName/OriginalName", Key="NewName")
client.delete_object(Bucket="BucketName", Key="OriginalName")

我遇到了以下错误: botocore.exceptions.ClientError: 调用CopyObject操作时发生错误(NoSuchBucket):指定的存储桶不存在。我设置了Bucket='xyz-abc-yzd',其中'xyz-abc-yzd'是我的存储桶名称。 在设置存储桶名称/键时是否有任何约定? - MikA
我可以使用“list_buckets()”列出相同的存储桶。 - MikA
9
可能可以节省其他用户的时间。CopySource 参数应包含 BucketNameKeyName,因此 OriginalName 并不完全等同于对象键名。 - Trein
@Trein - 谢谢!我在这里一直在想“这是什么鬼”。 - Darragh Enright
3
正如@Trein提到的,参数已经改变。CopySource 应该有以下结构: {'Bucket': 'string', 'Key': 'string', 'VersionId': 'string'}。这是参考文档。http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.copy_object - user666
1
就性能而言,我发现client.copy_object()client.copy()慢得多。这是因为后者使用多线程以分块的方式上传对象。 - Radu

19

以下是更新的Boto3文档中针对copy()方法的示例,该方法也适用于copy_object()方法,并且似乎现在是必需的语法:

copy_source = {'Bucket': 'source__bucket', 'Key': 'my_folder/my_file'}
s3.copy_object(CopySource = copy_source, Bucket = 'dest_bucket', Key = 'new_folder/my_file')
s3.delete_object(Bucket = 'source_bucket', Key = 'my_folder/my_file')

来自以上链接的文档注释:

CopySource(字典)--源存储桶的名称,源对象的键名和可选的源对象版本ID。字典格式为:{'Bucket': 'bucket', 'Key': 'key', 'VersionId': 'id'}。请注意,VersionId键是可选的,可以省略。


1
我认为你的意思是使用 client 而不是 s3,因为在 boto3 v1.9.83 中 's3.ServiceResource' object has no attribute 'copy_object'。看一下 @MikA 的答案,它使用资源来复制。 - Joe Haddad
1
这对我起作用了。s3 应该是 s3 客户端而不是资源。 - Avinash Dalvi

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