L' boto.s3.key.Key
objet de Boto 2 avait une exists
méthode qui vérifiait si la clé existait sur S3 en faisant une requête HEAD et en regardant le résultat, mais il semble que cela n'existe plus. Vous devez le faire vous-même:
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()
fait une requête HEAD pour une seule clé, ce qui est rapide, même si l'objet en question est volumineux ou si vous avez de nombreux objets dans votre compartiment.
Bien sûr, vous pouvez vérifier si l'objet existe parce que vous prévoyez de l'utiliser. Si tel est le cas, vous pouvez simplement oublier le load()
et faire un get()
ou download_file()
directement, puis gérer le cas d'erreur ici.
boto3
, il semble que le mieux que vous puissiez faire pour le moment est d'appelerhead_object
pour essayer de récupérer les métadonnées de la clé, puis de gérer l'erreur qui en résulte si elle n'existe pas.exists
booléen disparaisse, et il est plus clair (j'espère!) Que les gens sont censés adapter cela à leur situation.e.response['Error']['Code']
avoir une valeur comme"NoSuchKey"
, non"404"
. Je n'ai pas vérifié si cela était dû à une différence dans les versions de la bibliothèque ou à un changement dans l'API elle-même depuis que cette réponse a été écrite. Quoi qu'il en soit, dans ma version de boto3, une approche plus courte que la vérificatione.response['Error']['Code']
consiste à attraper seulements3.meta.client.exceptions.NoSuchKey
en premier lieu.client
(par opposition à aresource
), faites à las3.head_object(Bucket='my_bucket', Key='my_key')
place des3.Object(...).load()
Je ne suis pas un grand fan de l'utilisation d'exceptions pour le flux de contrôle. C'est une approche alternative qui fonctionne dans boto3:
la source
Le moyen le plus simple que j'ai trouvé (et probablement le plus efficace) est le suivant:
la source
s3 = boto3.client('s3')
if e.response['ResponseMetadata']['HTTPStatusCode'] == 404:
Dans Boto3, si vous recherchez un dossier (préfixe) ou un fichier à l'aide de list_objects. Vous pouvez utiliser l'existence de «Contenu» dans le dict de la réponse pour vérifier si l'objet existe. C'est une autre façon d'éviter les captures try / except comme le suggère @EvilPuppetMaster
la source
s3:GetObject
autorisations mais uniquement less3:ListBucket
autorisationsNon seulement
client
maisbucket
aussi:la source
bucket.Object(key).last_modified
.Vous pouvez utiliser S3F , qui est essentiellement un wrapper autour de boto3 qui expose les opérations typiques de style de système de fichiers:
la source
la source
FWIW, voici les fonctions très simples que j'utilise
la source
En supposant que vous vouliez simplement vérifier si une clé existe (au lieu de l'écraser tranquillement), faites d'abord cette vérification:
la source
Cela peut vérifier à la fois le préfixe et la clé, et récupère au plus 1 clé.
la source
Essayez ceci simple
la source
Si vous en avez moins de 1000 dans un répertoire ou un compartiment, vous pouvez en obtenir un ensemble et après vérifier si une telle clé dans cet ensemble:
Un tel code fonctionne même s'il
my/dir
n'existe pas.http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
la source
la source
Pour boto3, ObjectSummary peut être utilisé pour vérifier si un objet existe.
Dans ObjectSummary.load
Cela montre que vous pouvez utiliser
ObjectSummary
au lieu deObject
si vous prévoyez de ne pas utiliserget()
. Laload()
fonction ne récupère pas l'objet, elle obtient uniquement le résumé.la source
Voici une solution qui fonctionne pour moi. Une mise en garde est que je connais le format exact de la clé à l'avance, donc je ne liste que le fichier unique
la source
vous pouvez utiliser Boto3 pour cela.
Ici, la clé est le chemin que vous souhaitez vérifier existe ou non
la source
%timeit
test, cela semble l'option la plus rapideC'est vraiment simple avec la
get()
méthodela source
Il existe un moyen simple de vérifier si le fichier existe ou non dans le compartiment S3. Nous n'avons pas besoin d'utiliser une exception pour cela
la source
object_name
existe dans le compartiment. Par exemplemy_file.txt.oldversion
, retournera un faux positif si vous vérifiezmy_file.txt
. Un peu un cas de pointe pour la plupart, mais pour quelque chose d'aussi large que "le fichier existe-t-il" que vous êtes susceptible d'utiliser dans toute votre application mérite probablement d'être pris en considération.Si vous recherchez une clé équivalente à un répertoire, vous voudrez peut-être cette approche
Cela fonctionne pour une clé parente ou une clé qui équivaut à un fichier ou une clé qui n'existe pas. J'ai essayé l'approche préférée ci-dessus et j'ai échoué sur les clés parent.
la source
J'ai remarqué que juste pour attraper l'exception en utilisant,
botocore.exceptions.ClientError
nous devons installer botocore. botocore occupe 36 Mo d'espace disque. Ceci est particulièrement impactant si nous utilisons les fonctions aws lambda. À la place de cela, si nous utilisons simplement l'exception, nous pouvons ignorer l'utilisation de la bibliothèque supplémentaire!Le code ressemble à ceci. Veuillez partager vos pensées:
la source
En suivant simplement le fil de discussion, quelqu'un peut-il conclure quel est le moyen le plus efficace de vérifier si un objet existe dans S3?
Je pense que head_object pourrait gagner car il vérifie simplement les métadonnées qui sont plus légères que l'objet lui-même
la source
De https://www.peterbe.com/plog/fastest-way-to-find-out-if-a-file-exists-in-s3, il est indiqué que c'est la méthode la plus rapide:
la source
Check-out
de Boto S3 Docs
Vous pouvez simplement appeler bucket.get_key (keyname) et vérifier si l'objet renvoyé est None.
la source