Amazon S3 boto - как удалить папку?

Я создал папку в s3 с именем "test", и я нажимаю " test_1.jpg", " test_2.в JPG" в "тест".

теперь я хочу использовать boto для удаления папки "test".

Что делать?

4 ответов


здесь нет папки в 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 list keys иногда возвращает ключ каталога.


Я чувствую, что прошло некоторое время, и у 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


можно использовать ведро.delete_keys() со списком Ключей (с большим количеством ключей я обнаружил, что это на порядок быстрее, чем с помощью ключа.исключать.)

что-то вроде этого:

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)

небольшое улучшение решения Патрика. Как вы, возможно, знаете, оба list_objects() и delete_objects() имеют предел объекта 1000. Вот почему вам нужно разбить список на страницы и удалить куски. Это довольно универсальный и вы можете дать Prefix to 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)