web-dev-qa-db-fra.com

Amazon S3 boto - comment supprimer un dossier?

J'ai créé un dossier dans s3 nommé "test" et j'ai poussé "test_1.jpg", "test_2.jpg" dans "test".

Comment puis-je utiliser boto pour supprimer le dossier "test"?

48
wade huang

Il n'y a aucun dossier dans S3. Au lieu de cela, les clés forment un espace de noms plat. Cependant, une clé avec des barres obliques dans son nom apparaît spécialement dans certains programmes, y compris la console AWS (voir par exemple Amazon S3 boto - comment créer un dossier? ).

Au lieu de supprimer "un répertoire", vous pouvez (et devez) lister les fichiers par préfixe et supprimer. En substance:

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

Cependant, les autres réponses obtenues sur cette page proposent des approches plus efficaces.


Notez que le préfixe est simplement recherché à l'aide d'une recherche de chaîne fictive. Si le préfixe était your/directory, c'est-à-dire que sans la barre oblique de fin ajoutée, le programme supprimera également heureusement your/directory-that-you-wanted-to-remove-is-definitely-not-t‌​his-one.

Pour plus d'informations, voir Les clés de la liste Soto boto retournent parfois la clé du répertoire.

46
Antti Haapala

Voici la version 2018 (presque 2019):

s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
bucket.objects.filter(Prefix="myprefix/").delete()
61
Raz

Je pense que cela fait un moment et boto3 a plusieurs façons différentes d'atteindre cet objectif. Cela suppose que vous souhaitez supprimer le test "dossier" et tous ses objets Voici une façon:

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)

Cela devrait faire deux demandes, une pour récupérer les objets dans le dossier, la seconde pour supprimer tous les objets dans ledit dossier.

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

41
Patrick

Vous pouvez utiliser bucket.delete_keys () avec une liste de clés (avec un grand nombre de clés, j'ai trouvé que c'était un ordre de grandeur plus rapide que d'utiliser key.delete).

Quelque chose comme ça:

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)
19
David Fooks

Une légère amélioration par rapport à la solution de Patrick. Comme vous le savez peut-être, list_objects() et delete_objects() ont une limite d'objet de 1000. C'est pourquoi vous devez paginer la liste et la supprimer en morceaux. C'est assez universel et vous pouvez donner Prefix à paginator.paginate() pour supprimer les sous-répertoires/chemins

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)
17
dmitrybelyakov