El boto.s3.key.Key
objeto de Boto 2 solía tener un exists
método que verificaba si la clave existía en S3 haciendo una solicitud HEAD y mirando el resultado, pero parece que ya no existe. Tienes que hacerlo tú mismo:
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()
realiza una solicitud HEAD para una sola clave, que es rápida, incluso si el objeto en cuestión es grande o si tiene muchos objetos en su depósito.
Por supuesto, es posible que esté verificando si el objeto existe porque planea usarlo. Si ese es el caso, puede olvidarse del load()
y hacer un get()
o download_file()
directamente, luego manejar el caso de error allí.
boto3
, parece que lo mejor que puede hacer en este momento es llamarhead_object
para intentar obtener los metadatos de la clave, luego manejar el error resultante si no existe.exists
booleano desaparezca, y es más claro (¡espero!) Que se supone que las personas deben adaptar esto a su situación.e.response['Error']['Code']
tiene un valor como"NoSuchKey"
, no"404"
. No he comprobado si esto se debe a una diferencia en las versiones de la biblioteca o un cambio en la API en sí desde que se escribió esta respuesta. De cualquier manera, en mi versión de boto3, un enfoque más corto que verificare.response['Error']['Code']
es atrapar solos3.meta.client.exceptions.NoSuchKey
en primer lugar.client
(en lugar de aresource
), hágalo ens3.head_object(Bucket='my_bucket', Key='my_key')
lugar des3.Object(...).load()
No soy un gran fanático del uso de excepciones para el flujo de control. Este es un enfoque alternativo que funciona en boto3:
fuente
La forma más fácil que encontré (y probablemente la más eficiente) es esta:
fuente
s3 = boto3.client('s3')
if e.response['ResponseMetadata']['HTTPStatusCode'] == 404:
En Boto3, si está buscando una carpeta (prefijo) o un archivo usando list_objects. Puede usar la existencia de 'Contenido' en la respuesta dict como una verificación de si el objeto existe. Es otra forma de evitar el intento / excepto las capturas como sugiere @EvilPuppetMaster
fuente
s3:GetObject
permisos solo loss3:ListBucket
permisosNo solo
client
sinobucket
también:fuente
bucket.Object(key).last_modified
.Puede usar S3F , que es esencialmente un envoltorio alrededor de boto3 que expone las operaciones típicas de estilo de sistema de archivos:
fuente
fuente
FWIW, aquí están las funciones muy simples que estoy usando
fuente
Suponiendo que solo desea verificar si existe una clave (en lugar de sobreescribirla silenciosamente), primero haga esta verificación:
fuente
Esto podría verificar tanto el prefijo como la clave, y obtiene como máximo 1 clave.
fuente
Prueba esto simple
fuente
Si tiene menos de 1000 en un directorio o depósito, puede obtener un conjunto de ellos y luego verificar si dicha clave en este conjunto:
Tal código funciona incluso si
my/dir
no existe.http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2
fuente
fuente
Para boto3, ObjectSummary se puede usar para verificar si existe un objeto.
En ObjectSummary.load
Esto muestra que puede usar en
ObjectSummary
lugar deObject
si planea no usarget()
. Laload()
función no recupera el objeto, solo obtiene el resumen.fuente
Aquí hay una solución que funciona para mí. Una advertencia es que conozco el formato exacto de la clave con anticipación, por lo que solo enumero el archivo único
fuente
puedes usar Boto3 para esto.
Aquí la clave es la ruta que desea verificar existe o no
fuente
%timeit
prueba, esta parece ser la opción más rápidaEs muy simple con el
get()
método.fuente
Hay una manera simple por la cual podemos verificar si el archivo existe o no en el depósito S3. No necesitamos usar excepciones para esto
fuente
object_name
existe en el depósito. Por ejemplomy_file.txt.oldversion
, devolverá un falso positivo si verificamy_file.txt
. Es un caso marginal para la mayoría, pero para algo tan amplio como "existe el archivo" que probablemente usará en toda su aplicación, probablemente valga la pena tenerlo en cuenta.Si busca una clave que sea equivalente a un directorio, es posible que desee este enfoque
Esto funciona para una clave principal o una clave que equivale a un archivo o una clave que no existe. Probé el enfoque favorito anterior y fallé en las claves principales.
fuente
Noté que solo para detectar la excepción usando
botocore.exceptions.ClientError
necesitamos instalar botocore. botocore ocupa 36 millones de espacio en disco. Esto es particularmente impactante si usamos funciones aws lambda. En lugar de eso, si solo usamos la excepción, ¡podemos omitir el uso de la biblioteca adicional!El código se ve así. Por favor comparte tus pensamientos:
fuente
Simplemente siguiendo el hilo, ¿alguien puede concluir cuál es la forma más eficiente de verificar si un objeto existe en S3?
Creo que head_object podría ganar ya que solo verifica los metadatos que son más ligeros que el objeto en sí
fuente
Desde https://www.peterbe.com/plog/fastest-way-to-find-out-if-a-file-exists-in-s3, este es el método más rápido:
fuente
Revisa
de Boto S3 Docs
Simplemente puede llamar a bucket.get_key (keyname) y verificar si el objeto devuelto es None.
fuente