Amazon S3 Boto-如何删除文件夹?


87

我在s3中创建了一个名为“ test”的文件夹,并将“ test_1.jpg”,“ test_2.jpg”推入“ test”。

如何使用boto删除文件夹“ test”?


1
@pyCthon技术错误。再试一次。
devinbost

Answers:


61

S3中没有文件夹。而是,这些键形成一个平面命名空间。但是,名称中带有斜杠的键在某些程序中特别显示,包括AWS控制台(例如,参见Amazon S3 boto-如何创建文件夹?)。

除了删除“目录”,您可以(必须)通过前缀和删除列出文件。在本质上:

for key in bucket.list(prefix='your/directory/'):
    key.delete()

但是,此页面上其他已完成的答案提供了更有效的方法。


请注意,只是使用伪字符串搜索来搜索前缀。如果前缀为your/directory,即不添加尾部斜杠,程序也将很乐意删除your/directory-that-you-wanted-to-remove-is-definitely-not-t‌​his-one

有关更多信息,请参见S3 boto列表键有时返回目录键。


1
如何删除目录?删除该目录中的所有文件后,是否会自动删除该目录?
wade huang

谢谢。我已经完成了吧〜
韦德煌

@wadehuang-您可以分享有关删除文件夹的代码吗?
letsc

如何删除python中2天前的s3文件夹中的文件。我的s3中有此文件-桶/ 1 /备份/(10个文件)需要删除两天前的所有文件
艾玛艾玛艾玛

186

这是2018年(几乎2019年)的版本:

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()

22
到目前为止,这是最好的答案。
user554481 '19

1
有人可能会发现知道bucket.objects.all()。delete()清空整个存储桶而不删除它很有用,无论有多少个对象(即,不受影响,但限制为1000个项目)。参见:boto3.amazonaws.com/v1/documentation/api/latest/reference/…–
fabiog

1
嗨,拉兹(Raz),这对我不起作用,我只是得到空的方括号,即[]
Soyf

可悲的是,这不支持后缀:(
Anum Sheraz

很棒的是,该解决方案甚至可以处理1000多个对象
Mabyn

45

我感觉已经有一段时间了,boto3有几种不同的方法可以实现这一目标。假设您要删除测试“文件夹”及其所有对象,这是一种方法:

s3 = boto3.resource('s3')
objects_to_delete = s3.meta.client.list_objects(Bucket="MyBucket", Prefix="myfolder/test/")

delete_keys = {'Objects' : []}
delete_keys['Objects'] = [{'Key' : k} for k in [obj['Key'] for obj in objects_to_delete.get('Contents', [])]]

s3.meta.client.delete_objects(Bucket="MyBucket", Delete=delete_keys)

这应该发出两个请求,一个请求获取文件夹中的对象,第二个请求删除所述文件夹中的所有对象。

https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects


这是迄今为止最快的解决方案。
deepelement

2
这是最快的解决方案,但是请记住,list_objects它不能返回超过1000个键,因此您需要多次运行此代码。
lampslave '16

4
如果您有超过1k个对象,则可以使用分页器-请参阅下面的答案。
dmitrybelyakov '17

@deepelement,它仅适用于boto3,而不适用于boto
鳄梨

1
这个伟大的工程,你可以从一个Python拉姆达通过把上面的代码中lambda_handler功能运行它import boto3; def lambda_handler(event, context): '''Code from above'''。确保您授予Lambda权限以从S3删除并延长超时时间。
Nadir Sidi

21

您可以将bucket.delete_keys()与键列表一起使用(具有大量键,我发现这比使用key.delete快一个数量级)。

像这样:

delete_key_list = []
for key in bucket.list(prefix='/your/directory/'):
    delete_key_list.append(key)
    if len(delete_key_list) > 100:
        bucket.delete_keys(delete_key_list)
        delete_key_list = []

if len(delete_key_list) > 0:
    bucket.delete_keys(delete_key_list)

20

Patrick的解决方案略有改进。正如你可能知道,无论是list_objects()delete_objects()有1000的对象限制这就是为什么你必须进行分页上市和块删除。这是非常普遍的,你可以给Prefixpaginator.paginate()删除子目录/路径

client = boto3.client('s3', **credentials)
paginator = client.get_paginator('list_objects_v2')
pages = paginator.paginate(Bucket=self.bucket_name)

delete_us = dict(Objects=[])
for item in pages.search('Contents'):
    delete_us['Objects'].append(dict(Key=item['Key']))

    # flush once aws limit reached
    if len(delete_us['Objects']) >= 1000:
        client.delete_objects(Bucket=bucket, Delete=delete_us)
        delete_us = dict(Objects=[])

# flush rest
if len(delete_us['Objects']):
    client.delete_objects(Bucket=bucket, Delete=delete_us)

2
如果要限制为“目录” Prefixpaginator.paginate()请使用“查看所有选项”中的关键字:boto3.readthedocs.io/en/latest/reference/services/…–
乍得

1
使用@ChadPrefix建议的过滤器,我必须在删除之前添加检查(因为我的一些S3前缀不存在/没有对象)if item is not None
y2k-shubham

1

如果在S3存储桶上启用了版本控制:

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.object_versions.filter(Prefix="myprefix/").delete()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.