Obiekt Boto 2 miał boto.s3.key.Key
kiedyś exists
metodę, która sprawdzała, czy klucz istnieje na S3, wykonując żądanie HEAD i patrząc na wynik, ale wydaje się, że już go nie ma. Musisz to zrobić sam:
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()
wykonuje żądanie HEAD dla pojedynczego klucza, co jest szybkie, nawet jeśli dany obiekt jest duży lub masz wiele obiektów w swoim zasobniku.
Oczywiście możesz sprawdzić, czy obiekt istnieje, ponieważ planujesz go użyć. Jeśli tak jest, możesz po prostu zapomnieć o load()
i zrobić get()
lub download_file()
bezpośrednio, a następnie obsłużyć tam przypadek błędu.
boto3
Wydaje się bowiem , że najlepsze, co możesz teraz zrobić, to zadzwonić,head_object
aby spróbować pobrać metadane dla klucza, a następnie obsłużyć wynikowy błąd, jeśli nie istnieje.exists
logicznej i jest jaśniejsze (mam nadzieję!), Że ludzie powinni dostosować to do swojej sytuacji.e.response['Error']['Code']
wartość taką jak"NoSuchKey"
nie"404"
. Nie sprawdzałem, czy jest to spowodowane różnicą w wersjach biblioteki, czy zmianą samego API od czasu napisania tej odpowiedzi. Tak czy inaczej, w mojej wersji boto3 krótszym podejściem niż sprawdzaniee.response['Error']['Code']
jest złapanie tylkos3.meta.client.exceptions.NoSuchKey
w pierwszej kolejności.client
(w przeciwieństwie do aresource
), zróbs3.head_object(Bucket='my_bucket', Key='my_key')
zamiasts3.Object(...).load()
Nie jestem wielkim fanem używania wyjątków dla przepływu sterowania. To jest alternatywne podejście, które działa w boto3:
źródło
Najłatwiejszy sposób, jaki znalazłem (i prawdopodobnie najbardziej wydajny), to:
źródło
s3 = boto3.client('s3')
if e.response['ResponseMetadata']['HTTPStatusCode'] == 404:
W Boto3, jeśli sprawdzasz folder (prefiks) lub plik za pomocą list_objects. Możesz użyć istnienia „Contents” w dyktandzie odpowiedzi jako sprawdzenia, czy obiekt istnieje. Jest to inny sposób na uniknięcie prób / wyjątków, jak sugeruje @EvilPuppetMaster
źródło
s3:GetObject
uprawnień tylkos3:ListBucket
uprawnieniaNie tylko,
client
alebucket
też:źródło
bucket.Object(key).last_modified
.Możesz użyć S3F , który jest zasadniczo opakowaniem wokół boto3, które ujawnia typowe operacje w stylu systemu plików:
źródło
źródło
FWIW, oto bardzo proste funkcje, których używam
źródło
Zakładając, że chcesz tylko sprawdzić, czy klucz istnieje (zamiast po cichu go nadpisywać), najpierw zrób to sprawdzenie:
źródło
Wypróbuj to proste
źródło
Może to sprawdzić zarówno prefiks, jak i klucz i pobrać maksymalnie 1 klucz.
źródło
Jeśli masz mniej niż 1000 w katalogu lub wiadrze, możesz pobrać ich zestaw i po sprawdzeniu, czy taki klucz jest w tym zestawie:
Taki kod działa nawet jeśli
my/dir
nie istnieje.http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
źródło
źródło
W przypadku boto3 ObjectSummary może służyć do sprawdzenia, czy obiekt istnieje.
W ObjectSummary.load
To pokazuje, że możesz użyć
ObjectSummary
zamiast,Object
jeśli planujesz nie używaćget()
.load()
Funkcja nie odebrania obiektu to tylko uzyska podsumowanie.źródło
Oto rozwiązanie, które działa dla mnie. Jedynym zastrzeżeniem jest to, że z wyprzedzeniem znam dokładny format klucza, więc wymieniam tylko jeden plik
źródło
możesz do tego użyć Boto3.
Tutaj kluczem jest ścieżka, którą chcesz sprawdzić, czy istnieje, czy nie
źródło
%timeit
testu wydaje się, że jest to najszybsza opcjaget()
Metoda jest naprawdę prostaźródło
Jest jeden prosty sposób, dzięki któremu możemy sprawdzić, czy plik istnieje w zasobniku S3, czy nie. Nie musimy do tego używać wyjątków
źródło
object_name
istnieje w zasobniku. Np. Zwrócimy_file.txt.oldversion
fałszywie dodatni wynik, jeśli sprawdziszmy_file.txt
. Dla większości jest to trochę skrajna sprawa, ale w przypadku czegoś tak szerokiego, jak „czy plik istnieje”, którego prawdopodobnie użyjesz w swojej aplikacji, prawdopodobnie warto wziąć pod uwagę.Jeśli szukasz klucza, który jest odpowiednikiem katalogu, możesz chcieć tego podejścia
Działa to dla klucza nadrzędnego lub klucza równego plikowi lub klucza, który nie istnieje. Wypróbowałem preferowane podejście powyżej i zawiodłem na kluczach nadrzędnych.
źródło
Zauważyłem, że aby złapać wyjątek za pomocą
botocore.exceptions.ClientError
, musimy zainstalować botocore. botocore zajmuje 36M miejsca na dysku. Ma to szczególne znaczenie, jeśli używamy funkcji lambda aws. Zamiast tego, jeśli użyjemy tylko wyjątku, możemy pominąć korzystanie z dodatkowej biblioteki!Kod wygląda następująco. Podziel się swoimi przemyśleniami:
źródło
Czy po prostu podążając za wątkiem, ktoś może stwierdzić, który z nich jest najbardziej efektywnym sposobem sprawdzenia, czy obiekt istnieje w S3?
Myślę, że head_object może wygrać, ponieważ sprawdza tylko metadane, które są jaśniejsze niż sam obiekt
źródło
Z https://www.peterbe.com/plog/fastest-way-to-find-out-if-a-file-exists-in-s3 wskazuje się, że jest to najszybsza metoda:
źródło
Sprawdzić
z Boto S3 Docs
Możesz po prostu zadzwonić do bucket.get_key (nazwa klucza) i sprawdzić, czy zwrócony obiekt ma wartość Brak.
źródło