Ich habe in s3 einen Ordner mit dem Namen "test" erstellt und "test_1.jpg", "test_2.jpg" in "test" verschoben.
Wie kann ich mit boto den Ordner "test" löschen?
Ich habe in s3 einen Ordner mit dem Namen "test" erstellt und "test_1.jpg", "test_2.jpg" in "test" verschoben.
Wie kann ich mit boto den Ordner "test" löschen?
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öschen your/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.
Hier ist die Version 2018 (fast 2019):
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()
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
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 boto
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.
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 Prefix
zu paginator.paginate()
zu löschen Unterverzeichnisse / Pfade
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
von @Chad vorgeschlagenen Filter musste ich if item is not None
vor dem Löschen eine Prüfung hinzufügen (da einige meiner S3-Präfixe nicht existierten / keine Objekte hatten)