@pyCthon Falsche Technologie. Versuchen Sie es nochmal.
Devinbost
Antworten:
61
In S3 sind keine Ordner vorhanden. Stattdessen bilden die Schlüssel einen flachen Namespace. Ein Schlüssel mit Schrägstrichen im Namen wird jedoch speziell in einigen Programmen angezeigt, einschließlich der AWS-Konsole (siehe zum Beispiel Amazon S3 Boto - Wie erstelle ich einen Ordner? ).
Anstatt "ein Verzeichnis" zu löschen, können (und müssen) Sie Dateien nach Präfix auflisten und löschen. Im Wesentlichen:
for key in bucket.list(prefix='your/directory/'):
key.delete()
Die anderen Antworten auf dieser Seite bieten jedoch effizientere Ansätze.
Beachten Sie, dass das Präfix nur mit der Dummy-Zeichenfolgensuche durchsucht wird. Wenn das Präfix your/directorywäre, dh ohne den angehängten Schrägstrich, würde das Programm auch gerne löschen your/directory-that-you-wanted-to-remove-is-definitely-not-this-one.
Wie lösche ich das Verzeichnis? Wird dieses Verzeichnis automatisch gelöscht, wenn alle Dateien in diesem Verzeichnis gelöscht werden?
Wade Huang
Vielen Dank .. Ich habe es beendet ~
Wade Huang
@wadehuang - Können Sie Ihren Code zum Löschen von Ordnern freigeben?
Letsc
So löschen Sie Dateien in einem Ordner von s3, die in Python 2 Tage alt sind. Habe dies in meinem s3 - Bucket / 1 / Backups / (10 Dateien) muss alle Dateien entfernen, die zwei Tage alt sind
Jemand könnte es nützlich finden zu wissen, dass Bucket.objects.all (). delete () den gesamten Bucket leert, ohne ihn zu löschen, unabhängig davon, wie viele Objekte es gibt (dh es ist nicht betroffen, aber das Limit von 1000 Elementen). Siehe: boto3.amazonaws.com/v1/documentation/api/latest/reference/…
fabiog
1
Hallo Raz, das funktioniert bei mir nicht, ich bekomme einfach leere eckige Klammern, dh []
Soyf
Leider unterstützt dies kein Suffix :(
Anum Sheraz
Das Tolle ist, dass diese Lösung auch mit mehr als 1000 Objekten
funktioniert
45
Ich habe das Gefühl, dass es eine Weile her ist und boto3 verschiedene Möglichkeiten hat, dieses Ziel zu erreichen. Dies setzt voraus , Sie löschen möchten Test „Ordner“ und alle seine Objekte Hier ist eine Möglichkeit:
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)
Dies sollte zwei Anforderungen stellen, eine zum Abrufen der Objekte im Ordner und die zweite zum Löschen aller Objekte in diesem Ordner.
Dies ist die schnellste Lösung list_objects. Beachten Sie jedoch, dass nicht mehr als 1000 Schlüssel zurückgegeben werden können, sodass Sie diesen Code mehrmals ausführen müssen.
Lampensklave
4
Sie können Paginator verwenden, wenn Sie mehr als 1k Objekte haben - siehe meine Antwort unten.
Dmitrybelyakov
@deepelement, und es funktioniert nur in boto3, nicht boto
avocado
1
Dies funktioniert hervorragend und Sie können es von einem Python-Lambda aus ausführen, indem Sie den obigen Code in eine lambda_handler-Funktion einfügen : import boto3; def lambda_handler(event, context): '''Code from above'''. Stellen Sie sicher, dass Sie Ihrem Lambda die Berechtigung zum Löschen aus S3 erteilen und das Zeitlimit verlängern.
Nadir Sidi
21
Sie können Bucket.delete_keys () mit einer Liste von Schlüsseln verwenden (bei einer großen Anzahl von Schlüsseln war dies eine Größenordnung schneller als bei Verwendung von key.delete).
Etwas wie das:
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)
Eine leichte Verbesserung von Patricks Lösung. Wie Sie vielleicht wissen, haben beide list_objects()und delete_objects()ein Objektlimit von 1000. Aus diesem Grund müssen Sie die Auflistung paginieren und in Blöcken löschen. Das ist ziemlich universell und Sie können geben Prefixzu paginator.paginate()zu löschen Unterverzeichnisse / Pfade
Und wenn Sie sich auf ein "Verzeichnis" beschränken möchten, verwenden Sie das PrefixSchlüsselwort in paginator.paginate()Alle Optionen anzeigen
Chad
1
Mit dem Prefixvon @Chad vorgeschlagenen Filter musste ich if item is not Nonevor dem Löschen eine Prüfung hinzufügen (da einige meiner S3-Präfixe nicht existierten / keine Objekte hatten)
y2k-shubham
1
Wenn die Versionierung im S3-Bucket aktiviert ist:
Antworten:
In S3 sind keine Ordner vorhanden. Stattdessen bilden die Schlüssel einen flachen Namespace. Ein Schlüssel mit Schrägstrichen im Namen wird jedoch speziell in einigen Programmen angezeigt, einschließlich der AWS-Konsole (siehe zum Beispiel Amazon S3 Boto - Wie erstelle ich einen Ordner? ).
Anstatt "ein Verzeichnis" zu löschen, können (und müssen) Sie Dateien nach Präfix auflisten und löschen. Im Wesentlichen:
for key in bucket.list(prefix='your/directory/'): key.delete()
Die anderen Antworten auf dieser Seite bieten jedoch effizientere Ansätze.
Beachten Sie, dass das Präfix nur mit der Dummy-Zeichenfolgensuche durchsucht wird. Wenn das Präfix
wäre, dh ohne den angehängten Schrägstrich, würde das Programm auch gerne löschenyour/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.Weitere Informationen finden Sie unter S3-Botolistenschlüssel. Manchmal wird der Verzeichnisschlüssel zurückgegeben.
quelle
Hier ist die Version 2018 (fast 2019):
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.objects.filter(Prefix="myprefix/").delete()
quelle
Ich habe das Gefühl, dass es eine Weile her ist und boto3 verschiedene Möglichkeiten hat, dieses Ziel zu erreichen. Dies setzt voraus , Sie löschen möchten Test „Ordner“ und alle seine Objekte Hier ist eine Möglichkeit:
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)
Dies sollte zwei Anforderungen stellen, eine zum Abrufen der Objekte im Ordner und die zweite zum Löschen aller Objekte in diesem Ordner.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
quelle
list_objects
. Beachten Sie jedoch, dass nicht mehr als 1000 Schlüssel zurückgegeben werden können, sodass Sie diesen Code mehrmals ausführen müssen.boto3
, nicht botoimport boto3; def lambda_handler(event, context): '''Code from above'''
. Stellen Sie sicher, dass Sie Ihrem Lambda die Berechtigung zum Löschen aus S3 erteilen und das Zeitlimit verlängern.Sie können Bucket.delete_keys () mit einer Liste von Schlüsseln verwenden (bei einer großen Anzahl von Schlüsseln war dies eine Größenordnung schneller als bei Verwendung von key.delete).
Etwas wie das:
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)
quelle
Eine leichte Verbesserung von Patricks Lösung. Wie Sie vielleicht wissen, haben beide
list_objects()
unddelete_objects()
ein Objektlimit von 1000. Aus diesem Grund müssen Sie die Auflistung paginieren und in Blöcken löschen. Das ist ziemlich universell und Sie können gebenPrefix
zupaginator.paginate()
zu löschen Unterverzeichnisse / Pfadeclient = 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)
quelle
Prefix
Schlüsselwort inpaginator.paginate()
Alle Optionen anzeigenPrefix
von @Chad vorgeschlagenen Filter musste ichif item is not None
vor dem Löschen eine Prüfung hinzufügen (da einige meiner S3-Präfixe nicht existierten / keine Objekte hatten)Wenn die Versionierung im S3-Bucket aktiviert ist:
s3 = boto3.resource('s3') bucket = s3.Bucket('mybucket') bucket.object_versions.filter(Prefix="myprefix/").delete()
quelle