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ł your/directory, to znaczy bez dodanego końcowego ukośnika, program również zostałby szczęśliwie usunięty your/directory-that-you-wanted-to-remove-is-definitely-not-this-one.
ktoś może się przydać, aby wiedzieć, że bucket.objects.all (). delete () opróżnia cały zasobnik bez usuwania go, bez względu na to, ile jest obiektów (tj. nie ma na to wpływu, ale limit 1000 elementów). Zobacz: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog
1
Cześć Raz, to nie działa dla mnie, po prostu widzę puste nawiasy kwadratowe, tj. []
Soyf
Niestety, nie obsługuje to Suffix :(
Anum Sheraz
Wspaniałe jest to, że to rozwiązanie działa nawet z ponad 1000 obiektów
Mabyn
45
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.
To najszybsze rozwiązanie, ale pamiętaj, że list_objectsnie może zwrócić więcej niż 1000 kluczy, więc musisz wielokrotnie uruchamiać ten kod.
lampaslave
4
Możesz użyć paginatora, jeśli masz więcej niż 1k obiektów - zobacz moją odpowiedź poniżej.
dmitrybelyakov
@deepelement, i działa tylko w boto3, a nie boto
awokado,
1
Działa to doskonale, a można go uruchomić z lambda Python umieszczając powyższy kod w funkcji lambda_handler: 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.
Nadir Sidi
21
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ć Prefixsię paginator.paginate()aby usunąć podkatalogach / ścieżek
z Prefixfiltrem zasugerowanym przez @Chad musiałem dodać if item is not Noneczek przed usunięciem (ponieważ niektóre z moich prefiksów S3 nie istniały / nie miały obiektów)
y2k-shubham
1
Jeśli przechowywanie wersji jest włączone w zasobniku S3:
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ętyyour/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.
źródło
Oto wersja 2018 (prawie 2019):
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.objects.filter(Prefix="myprefix/").delete()
źródło
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
źródło
list_objects
nie może zwrócić więcej niż 1000 kluczy, więc musisz wielokrotnie uruchamiać ten kod.boto3
, a nie botoimport 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)
źródło
Niewielka poprawa w stosunku do rozwiązania Patricka. Jak być może wiesz, oba
list_objects()
idelete_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żekclient = 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)
źródło
Prefix
słowa kluczowego wpaginator.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)Jeśli przechowywanie wersji jest włączone w zasobniku S3:
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.object_versions.filter(Prefix="myprefix/").delete()
źródło