Utworzyłem folder w s3 o nazwie „test” i wrzuciłem „test_1.jpg”, „test_2.jpg” do „test”.
Jak mogę użyć boto, aby usunąć folder „test”?
Utworzyłem folder w s3 o nazwie „test” i wrzuciłem „test_1.jpg”, „test_2.jpg” do „test”.
Jak mogę użyć boto, aby usunąć folder „test”?
Odpowiedzi:
W S3 nie ma żadnych folderów. Zamiast tego klucze tworzą płaską przestrzeń nazw. Jednak klucz ze ukośnikami w nazwie pojawia się szczególnie w niektórych programach, w tym w konsoli AWS (zobacz na przykład boto Amazon S3 - jak utworzyć folder? ).
Zamiast usuwać „katalog”, możesz (i musisz) wyświetlać pliki według prefiksu i usuwać. W istocie:
for key in bucket.list(prefix='your/directory/'):
key.delete()
Jednak inne osiągnięte odpowiedzi na tej stronie zawierają bardziej wydajne podejścia.
Zwróć uwagę, że przedrostek jest po prostu przeszukiwany przy użyciu fikcyjnego wyszukiwania ciągów. Gdyby prefiks był , to znaczy bez dodanego końcowego ukośnika, program również zostałby szczęśliwie usunięty your/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.
Aby uzyskać więcej informacji, zobacz Klawisze listy boto S3 czasami zwracają klucz katalogu.
Oto wersja 2018 (prawie 2019):
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()
Czuję, że minęło trochę czasu i boto3 ma kilka różnych sposobów na osiągnięcie tego celu. Zakładamy, że chcesz usunąć testowy „folder” i wszystkie jego obiekty. Oto jeden sposób:
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)
Powinno to spowodować dwa żądania, jedno o pobranie obiektów z folderu, a drugie o usunięcie wszystkich obiektów w tym folderze.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
list_objects
nie może zwrócić więcej niż 1000 kluczy, więc musisz wielokrotnie uruchamiać ten kod.
boto3
, a nie boto
import boto3; def lambda_handler(event, context): '''Code from above'''
. Upewnij się, że pozwoliłeś swojej Lambdzie usunąć z S3 i przedłużyć limit czasu.
Możesz użyć bucket.delete_keys () z listą kluczy (przy dużej liczbie kluczy okazało się, że jest to o rząd wielkości szybsze niż użycie key.delete).
Coś takiego:
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)
Niewielka poprawa w stosunku do rozwiązania Patricka. Jak być może wiesz, oba list_objects()
i delete_objects()
mają limit liczby obiektów wynoszący 1000. Dlatego musisz dzielić listę i usuwać w fragmentach. To jest dość powszechne i można dać Prefix
się paginator.paginate()
aby usunąć podkatalogach / ścieżek
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)
Prefix
słowa kluczowego w paginator.paginate()
sekcji Zobacz wszystkie opcje: boto3.readthedocs.io/en/latest/reference/services/ ...
Prefix
filtrem zasugerowanym przez @Chad musiałem dodać if item is not None
czek przed usunięciem (ponieważ niektóre z moich prefiksów S3 nie istniały / nie miały obiektów)