web-dev-qa-db-fra.com

Comment obtenir la taille d'une collection boto3?

La façon dont j'ai utilisé est de transformer la collection en une liste et d'interroger la longueur:

s3 = boto3.resource('s3')
bucket = s3.Bucket('my_bucket')
size = len(list(bucket.objects.all()))

Cependant, cela force la résolution de toute la collection et empêche les avantages d'utiliser une collection en premier lieu. Y a-t-il une meilleure manière de faire cela?

12

Il est impossible d'obtenir le nombre de clés dans un compartiment sans répertorier tous les objets. Il s'agit d'une limitation d'AWS S3 (voir https://forums.aws.Amazon.com/thread.jspa?messageID=164220 ).

L'obtention des résumés d'objets (HEAD) n'obtient pas les données réelles. Cette opération devrait donc être relativement peu coûteuse. Si vous vous contentez de supprimer la liste, vous pouvez effectuer les opérations suivantes:

size = sum(1 for _ in bucket.objects.all())

Ce qui vous donnera le nombre d'objets sans construire de liste.

21
AChampion

Empruntant à une question similaire , une option pour extraire la liste complète des clés d’objet d’un préfixe de compartiment + consiste à utiliser la récursivité avec la méthode list_objects_v2 .

Cette méthode récupérera de manière récursive la liste des clés d'objet, 1000 clés à la fois.

Chaque demande à list_objects_v2 utilise l'argument StartAfter pour continuer à répertorier les clés après la dernière clé de la demande précédente.

import boto3

if __== '__main__':

    client = boto3.client('s3',
        aws_access_key_id     = 'access_key',
        aws_secret_access_key = 'secret_key'
    )

    def get_all_object_keys(bucket, prefix, start_after = '', keys = []):
        response = client.list_objects_v2(
            Bucket     = bucket,
            Prefix     = prefix,
            StartAfter = start_after
        )

        if 'Contents' not in response:
            return keys

        key_list = response['Contents']
        last_key = key_list[-1]['Key']

        keys.extend(key_list)

        return get_all_object_keys(bucket, prefix, last_key, keys)

    object_keys = get_all_object_keys('your_bucket', 'prefix/to/files')

    print(len(object_keys))
0
doremi

Pour mon cas d'utilisation, je voulais juste savoir si le dossier est vide ou non.

s3 = boto3.client('s3')
response = s3.list_objects(
        Bucket='your-bucket',
        Prefix='path/to/your/folder/',
)
print(len(response['Contents']))

Cela suffisait pour savoir si le dossier est vide. Notez qu'un dossier, s'il est créé manuellement dans la console S3, peut être considéré comme une ressource. Dans ce cas, si la longueur indiquée ci-dessus est supérieure à 1, le "dossier" S3 est vide.

0
andersan