Creé una carpeta en s3 llamada "prueba" y presioné "prueba_1.jpg", "prueba_2.jpg" en "prueba".
¿Cómo puedo usar boto para eliminar la carpeta "prueba"?
Creé una carpeta en s3 llamada "prueba" y presioné "prueba_1.jpg", "prueba_2.jpg" en "prueba".
¿Cómo puedo usar boto para eliminar la carpeta "prueba"?
Respuestas:
No hay carpetas en S3. En cambio, las claves forman un espacio de nombres plano. Sin embargo, una tecla con barras en su nombre se muestra especialmente en algunos programas, incluida la consola de AWS (consulte, por ejemplo, Amazon S3 boto: ¿cómo crear una carpeta? ).
En lugar de eliminar "un directorio", puede (y debe) enumerar los archivos por prefijo y eliminarlos. En esencia:
for key in bucket.list(prefix='your/directory/'):
key.delete()
Sin embargo, las otras respuestas logradas en esta página presentan enfoques más eficientes.
Observe que el prefijo solo se busca mediante la búsqueda de cadenas ficticias. Si el prefijo fuera , es decir, sin la barra inclinada al final, el programa también eliminaría felizmente your/directory
your/directory-that-you-wanted-to-remove-is-definitely-not-this-one
.
Para obtener más información, consulte S3 boto list keys a veces devuelve la clave de directorio.
Aquí está la versión 2018 (casi 2019):
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()
Siento que ha pasado un tiempo y boto3 tiene algunas formas diferentes de lograr este objetivo. Esto supone que desea eliminar la "carpeta" de prueba y todos sus objetos. Aquí hay una forma:
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)
Esto debería hacer dos solicitudes, una para buscar los objetos en la carpeta, la segunda para eliminar todos los objetos en dicha carpeta.
https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects
list_objects
no puede devolver más de 1000 claves, por lo que debe ejecutar este código varias veces.
boto3
, no boto
import boto3; def lambda_handler(event, context): '''Code from above'''
. Asegúrese de otorgarle permiso a Lambda para eliminar de S3 y extender el tiempo de espera.
Puede usar bucket.delete_keys () con una lista de claves (con una gran cantidad de claves, encontré que esto es un orden de magnitud más rápido que usar key.delete).
Algo como esto:
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)
Una ligera mejora en la solución de Patrick. Como se puede saber, tanto list_objects()
y delete_objects()
tienen un límite objetivo de 1000. Esta es la razón por lo que tiene que paginar lista y eliminar en trozos. Esto es bastante universal y puede darle Prefix
a paginator.paginate()
para borrar los subdirectorios / rutas
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
palabra clave en paginator.paginate()
Ver todas las opciones: boto3.readthedocs.io/en/latest/reference/services/…
Prefix
filtro sugerido por @Chad , tuve que agregar un if item is not None
cheque antes de la eliminación (ya que algunos de mis prefijos S3 no existían / no tenían objetos)