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

我在 s3中创建了一个名为“ test”的文件夹,并将“ test _ 1.jpg”、“ test _ 2.jpg”按到“ test”中。

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

105118 次浏览

在 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 列表键有时返回目录键。

你可以通过键列表使用 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)

我觉得已经有一段时间了,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

帕特里克溶液的一点改进。您可能知道,list_objects()delete_objects()的对象限制都是1000。这就是为什么你必须分页列表和删除块。这是相当通用的,您可以将 Prefix交给 paginator.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)

以下是2018年(接近2019年)的版本:

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

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

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

如果需要像我一样根据对象内容进行过滤,以下是您的逻辑的蓝图:

def get_s3_objects_batches(s3: S3Client, **base_kwargs):
kwargs = dict(MaxKeys=1000, **base_kwargs)
while True:
response = s3.list_objects_v2(**kwargs)
# to yield each and every file: yield from response.get('Contents', [])
yield response.get('Contents', [])
if not response.get('IsTruncated'):  # At the end of the list?
break
continuation_token = response.get('NextContinuationToken')
kwargs['ContinuationToken'] = continuation_token




def your_filter(b):
raise NotImplementedError()




session = boto3.session.Session(profile_name=profile_name)
s3client = session.client('s3')
for batch in get_s3_objects_batches(s3client, Bucket=bucket_name, Prefix=prefix):
to_delete = [{'Key': obj['Key']} for obj in batch if your_filter(obj)]
if to_delete:
s3client.delete_objects(Bucket=bucket_name, Delete={'Objects': to_delete})

# 使用 boto3删除文件夹 S3中的文件 #

def delete_from_minio():
"""
This function is used to delete files or folder inside the another Folder
"""
try:
logger.info("Deleting from minio")
aws_access_key_id='Your_aws_acess_key'
aws_secret_access_key = 'Your_aws_Secret_key'
host = 'your_aws_endpoint'
s3 = boto3.resource('s3', aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key ,
config=boto3.session.Config(signature_version='your_version'),
region_name="your_region",
endpoint_url=host ,
verify=False)
bucket = s3.Bucket('Your_bucket_name')
for obj in bucket.objects.filter(Prefix='Directory/Sub_Directory'):
s3.Object(bucket.name, obj.key).delete()
except Exception as e:
print(f"Error Occurred while deleting from the S3,{str(e)}")

希望这个有帮助:)