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


87

Я створив папку в s3 з назвою "test", і я вставив "test_1.jpg", "test_2.jpg" у "test".

Як я можу використовувати бото для видалення папки "test"?


1
@pyCthon Неправильна технологія. Спробуйте ще раз.
devinbost

Відповіді:


61

У S3 немає папок. Натомість ключі утворюють плоский простір імен. Однак ключ із нахиленими рисками в назві відображається спеціально в деяких програмах, включаючи консоль AWS (див., Наприклад, бото Amazon S3 - як створити папку? ).

Замість того, щоб видаляти "каталог", ви можете (і повинні) перераховувати файли за префіксом та видаляти. По суті:

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 іноді повертають ключ каталогу.


1
Як видалити каталог? Якщо цей каталог буде видалено автоматично, коли всі файли в ньому буде видалено?
wade huang

Дякую .. Я закінчив це ~
wade huang

@wadehuang - чи можете ви поділитися своїм кодом про видалення папок?
letsc

Як видалити файли в папці s3, яким у python 2 роки. мати це в моєму s3 - відро / 1 / резервні копії / (10 файлів) потрібно видалити всі файли, яким два дні
艾瑪艾瑪 艾瑪

190

Ось версія 2018 (майже 2019):

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

23
Це, безумовно, найкраща відповідь.
користувач554481

1
комусь може бути корисно знати, що bucket.objects.all (). delete () спорожнює весь сегмент, не видаляючи його, незалежно від кількості об’єктів (тобто це не впливає, але обмежується 1000 елементів). Див .: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog

1
Привіт Раз, це не працює для мене, я просто отримую порожні квадратні дужки, тобто []
Сойф,

На жаль, це не підтримує Суфікс :(
Анум Шераз,


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 ключів, тому вам потрібно запустити цей код кілька разів.
lamplave

4
Ви можете використовувати пагінатор, якщо у вас більше 1 тис. Об’єктів - див. Мою відповідь нижче.
dmitrybelyakov

@deepelement, і він працює лише в boto3, а не в бото
авокадо

1
Це прекрасно працює, і ви можете запустити його з лямбда Python, поставивши вище код в функції lambda_handler: import boto3; def lambda_handler(event, context): '''Code from above'''. Переконайтеся, що ви дали своєму Lambda дозвіл на видалення з S3 та продовження часу очікування.
Надір Сіді

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

Невелике вдосконалення рішення Патріка. Як ви могли знати, обидва 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)

2
А якщо ви хочете обмежитись "каталогом", використовуйте Prefixключове слово в paginator.paginate()Переглянути всі варіанти: boto3.readthedocs.io/en/latest/reference/services/…
Чад,

1
з Prefixфільтром, запропонованим @Chad , мені довелося додати if item is not Noneперевірку перед видаленням (оскільки деякі мої префікси S3 не існували / не мали об’єктів)
y2k-shubham

1

Якщо на сегменті S3 увімкнено версій:

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.object_versions.filter(Prefix="myprefix/").delete()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.