2012-07-11 56 views

Respuesta

33

Hay no carpetas en S3. En cambio, las claves forman un espacio de nombre plano. Sin embargo, una clave con barras en su nombre se muestra especialmente en algunos programas, incluida la consola de AWS (consulte, por ejemplo, Amazon S3 boto - how to create a folder?).

En lugar de eliminar "un directorio", puede (y debe) hacer una lista de archivos por prefijo y eliminar. En esencia:

for key in bucket.list(prefix='your/directory/'): 
    key.delete() 

Sin embargo, las otras respuestas logradas en esta página ofrecen enfoques más eficientes.


Observe que el prefijo se acaba de buscar utilizando la búsqueda de cadena ficticia. Si el prefijo era your/directory, es decir, sin la barra inclinada adjunta, el programa también eliminaría felizmente your/directory-that-you-wanted-to-remove-is-definitely-not-t‌​his-one.

Para obtener más información, ver S3 boto list keys sometimes returns directory key.

+0

¿Cómo eliminar el directorio? Si este directorio se eliminará automáticamente cuando se eliminen todos los archivos en este directorio? –

+0

Gracias .. Lo he terminado ~ –

+0

@wadehuang - ¿podría compartir su código sobre la eliminación de carpetas? – letsc

16

Puede utilizar bucket.delete_keys() con una lista de claves (con un gran número de claves Me pareció que para ser un orden de magnitud más rápido que utilizando 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) 
+0

Consulte la solución de Patrick para evitar solicitudes de N + 1 – deepelement

23

me siento que ha sido un tiempo y boto3 tiene unas cuantas formas diferentes de lograr este objetivo. Esto supone que desea borrar el prueba "carpeta" y todos sus objetos Aquí es una manera:

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 de la carpeta, el segundo para borrar todas las objetos en dicha carpeta.

https://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.delete_objects

+0

Esta es, con mucho, la solución más rápida. – deepelement

+0

Esta es la solución más rápida, pero tenga en cuenta que 'list_objects' no puede devolver más de 1000 claves, por lo que debe ejecutar este código varias veces. – lampslave

+1

Puede usar paginator si tiene más de 1k de objetos; consulte mi respuesta a continuación. – dmitrybelyakov

6

una ligera mejora en la solución de Patrick. Como ya sabrá, tanto list_objects() como delete_objects() tienen un límite de objeto de 1000. Por esta razón, tiene que paginar el listado y eliminarlo en fragmentos. Esto es bastante universal y puede darle a Prefixpaginator.paginate() para eliminar 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)