Das boto.s3.key.Key
Objekt von Boto 2 verfügte früher über eine exists
Methode, mit der überprüft wurde, ob der Schlüssel in S3 vorhanden war, indem eine HEAD-Anforderung ausgeführt und das Ergebnis angezeigt wurde. Es scheint jedoch, dass diese nicht mehr vorhanden ist. Du musst es selber machen:
import boto3
import botocore
s3 = boto3.resource('s3')
try:
s3.Object('my-bucket', 'dootdoot.jpg').load()
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code'] == "404":
# The object does not exist.
...
else:
# Something else has gone wrong.
raise
else:
# The object does exist.
...
load()
führt eine HEAD-Anforderung für einen einzelnen Schlüssel durch, was schnell ist, selbst wenn das betreffende Objekt groß ist oder Sie viele Objekte in Ihrem Bucket haben.
Natürlich prüfen Sie möglicherweise, ob das Objekt vorhanden ist, weil Sie es verwenden möchten. Wenn dies der Fall ist, können Sie das einfach vergessen load()
und ein get()
oder download_file()
direkt ausführen und dann den Fehlerfall dort behandeln.
boto3
, so scheint es das Beste was Sie im Moment tun können , ist zu nennen ,head_object
die Metadaten für den Schlüssel , um zu versuchen und zu holen, dann die resultierenden Fehler behandeln , wenn sie noch nicht existiert.exists
Boolesche Wert weg ist, und es ist klarer (ich hoffe!), Dass die Leute dies an ihre Situation anpassen sollen.e.response['Error']['Code']
ich einen Wert wie"NoSuchKey"
, nicht"404"
. Ich habe nicht überprüft, ob dies auf einen Unterschied in den Bibliotheksversionen oder auf eine Änderung in der API selbst zurückzuführen ist, seit diese Antwort geschrieben wurde. In beiden Fällen besteht in meiner Version von boto3 ein kürzerer Ansatz als das Überprüfene.response['Error']['Code']
darin, nurs3.meta.client.exceptions.NoSuchKey
an erster Stelle zu fangen .client
(im Gegensatz zu einemresource
) verwenden, tun Sie diess3.head_object(Bucket='my_bucket', Key='my_key')
anstelle vons3.Object(...).load()
Ich bin kein großer Fan von Ausnahmen für den Kontrollfluss. Dies ist ein alternativer Ansatz, der in boto3 funktioniert:
quelle
Der einfachste (und wahrscheinlich effizienteste) Weg, den ich gefunden habe, ist folgender:
quelle
s3 = boto3.client('s3')
if e.response['ResponseMetadata']['HTTPStatusCode'] == 404:
Wenn Sie in Boto3 mithilfe von list_objects nach einem Ordner (Präfix) oder einer Datei suchen. Sie können das Vorhandensein von 'Inhalt' im Antwortdiktat verwenden, um zu überprüfen, ob das Objekt vorhanden ist. Es ist eine andere Möglichkeit, die Versuche / Ausnahmen zu vermeiden, wie @EvilPuppetMaster vorschlägt
quelle
s3:GetObject
nur dies3:ListBucket
Berechtigungen erforderlich sindNicht nur,
client
sondernbucket
auch:quelle
bucket.Object(key).last_modified
.Sie können S3Fs verwenden , bei denen es sich im Wesentlichen um einen Wrapper um boto3 handelt, der typische Operationen im Dateisystemstil verfügbar macht:
quelle
quelle
FWIW, hier sind die sehr einfachen Funktionen, die ich benutze
quelle
Angenommen, Sie möchten nur überprüfen, ob ein Schlüssel vorhanden ist (anstatt ihn leise zu überschreiben), führen Sie zuerst diese Überprüfung durch:
quelle
Versuchen Sie dies einfach
quelle
Dies könnte sowohl das Präfix als auch den Schlüssel überprüfen und höchstens 1 Schlüssel abrufen.
quelle
Wenn Sie weniger als 1000 in einem Verzeichnis oder Bucket haben, können Sie diese festlegen und nach Überprüfung prüfen, ob ein solcher Schlüssel in dieser Gruppe enthalten ist:
Ein solcher Code funktioniert auch dann, wenn er
my/dir
nicht vorhanden ist.http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
quelle
quelle
Für boto3 kann ObjectSummary verwendet werden, um zu überprüfen, ob ein Objekt vorhanden ist.
In ObjectSummary.load
Dies zeigt, dass Sie
ObjectSummary
anstelle von verwenden können,Object
wenn Sie nicht verwenden möchtenget()
. Dieload()
Funktion ruft das Objekt nicht ab, sondern erhält nur die Zusammenfassung.quelle
Hier ist eine Lösung, die für mich funktioniert. Eine Einschränkung ist, dass ich das genaue Format des Schlüssels im Voraus kenne, sodass ich nur die einzelne Datei aufführe
quelle
Sie können dafür Boto3 verwenden.
Hier ist der Schlüssel der Pfad, den Sie überprüfen möchten, vorhanden oder nicht
quelle
%timeit
Test scheint dies die schnellste Option zu seinMit der
get()
Methode ist es wirklich einfachquelle
Es gibt eine einfache Möglichkeit, um zu überprüfen, ob eine Datei im S3-Bucket vorhanden ist oder nicht. Wir brauchen dafür keine Ausnahme zu verwenden
quelle
object_name
, im Bucket vorhanden ist. ZBmy_file.txt.oldversion
wird ein falsches Positiv zurückgegeben, wenn Sie nach suchenmy_file.txt
. Für die meisten ein Randfall, aber für etwas so Breites wie "Existiert die Datei", das Sie wahrscheinlich in Ihrer gesamten Anwendung verwenden, ist es wahrscheinlich wert, berücksichtigt zu werden.Wenn Sie einen Schlüssel suchen, der einem Verzeichnis entspricht, möchten Sie möglicherweise diesen Ansatz
Dies funktioniert für einen übergeordneten Schlüssel oder einen Schlüssel, der einer Datei oder einem nicht vorhandenen Schlüssel entspricht. Ich habe den oben beschriebenen bevorzugten Ansatz ausprobiert und bin bei den übergeordneten Schlüsseln fehlgeschlagen.
quelle
Ich habe festgestellt, dass
botocore.exceptions.ClientError
wir nur Botocore installieren müssen, um die Ausnahme mit zu fangen. Botocore belegt 36 Millionen Speicherplatz. Dies wirkt sich besonders aus, wenn wir aws-Lambda-Funktionen verwenden. Wenn wir nur eine Ausnahme verwenden, können wir stattdessen die zusätzliche Bibliothek überspringen!Der Code sieht so aus. Bitte teilen Sie Ihre Gedanken:
quelle
Kann jemand, der dem Thread folgt, feststellen, welcher der effizienteste Weg ist, um zu überprüfen, ob ein Objekt in S3 vorhanden ist?
Ich denke, head_object könnte gewinnen, da es nur die Metadaten überprüft, die leichter sind als das eigentliche Objekt
quelle
Unter https://www.peterbe.com/plog/fastest-way-to-find-out-if-a-file-exists-in-s3 wird darauf hingewiesen, dass dies die schnellste Methode ist:
quelle
Auschecken
von Boto S3 Docs
Sie können einfach buck.get_key (Schlüsselname) aufrufen und prüfen, ob das zurückgegebene Objekt None ist.
quelle