81 votes

Comment obtenir plus de 1000 objets de S3 en utilisant list_objects_v2 ?

J'ai plus de 500 000 objets sur S3. J'essaie d'obtenir la taille de chaque objet. Je utilise le code Python suivant pour cela

import boto3

bucket = 'bucket'
prefix = 'prefix'

contents = boto3.client('s3').list_objects_v2(Bucket=bucket,  MaxKeys=1000, Prefix=prefix)["Contents"]

for c in contents:
    print(c["Size"])

Mais cela ne m'a donné que la taille des 1000 premiers objets. D'après la documentation, nous ne pouvons pas obtenir plus de 1000. Y a-t-il un moyen d'obtenir plus que cela?

1 votes

Alternatively, you could use Amazon S3 Inventory to obtain a daily listing of the bucket. En français : Alternativement, vous pourriez utiliser Amazon S3 Inventory pour obtenir une liste quotidienne du bucket.

127voto

J Tasker Points 851

La classe Paginator intégrée à boto3 est le moyen le plus simple de contourner la limitation de 1000 enregistrements de list-objects-v2. Cela peut être mis en œuvre de la manière suivante

s3 = boto3.client('s3')

paginator = s3.get_paginator('list_objects_v2')
pages = paginator.paginate(Bucket='bucket', Prefix='prefix')

for page in pages:
    for obj in page['Contents']:
        print(obj['Size'])

Pour plus de détails : https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Paginator.ListObjectsV2

2 votes

C'était exactement ce dont j'avais besoin pour évaluer la liste actuelle des compartiments s3 auxquels j'ai accès. Je me demandais pourquoi ils avaient tous 1000 dedans haha.

0 votes

C'est la RÉPONSE !

1 votes

Y a-t-il une limite supérieure, puisque les pages sont en mémoire que se passe-t-il s'il y a un très grand nombre d'objets.

69voto

AKX Points 14236

Utilisez le ContinuationToken retourné dans la réponse en tant que paramètre pour les appels ultérieurs, jusqu'à ce que la valeur IsTruncated retournée dans la réponse soit fausse.

Ceci peut être factorisé dans une fonction génératrice soignée :

def get_all_s3_objects(s3, **base_kwargs):
    continuation_token = None
    while True:
        list_kwargs = dict(MaxKeys=1000, **base_kwargs)
        if continuation_token:
            list_kwargs['ContinuationToken'] = continuation_token
        response = s3.list_objects_v2(**list_kwargs)
        yield from response.get('Contents', [])
        if not response.get('IsTruncated'):  # À la fin de la liste ?
            break
        continuation_token = response.get('NextContinuationToken')

for file in get_all_s3_objects(boto3.client('s3'), Bucket=bucket, Prefix=prefix):
    print(file['Size'])

2 votes

Y a-t-il un moyen de distribuer la création de cette liste? Parcourir le générateur pour créer la liste prend des heures.

1 votes

A fonctionné pour moi comme un charme!

18voto

seeiespi Points 48

Si vous n'avez PAS BESOIN d'utiliser le boto3.client vous pouvez utiliser boto3.resource pour obtenir une liste complète de vos fichiers :

s3r = boto3.resource('s3')
bucket = s3r.Bucket('nom_du_bucket')
files_in_bucket = list(bucket.objects.all())

Ensuite, pour obtenir la taille :

tailles = [f.size for f in files_in_bucket]

En fonction de la taille de votre bucket, cela pourrait prendre quelques minutes.

1 votes

Y a-t-il un avantage à utiliser la ressource?

1 votes

Il existe certaines méthodes qui peuvent être trouvées dans la ressource et pas dans le client et vice-versa. Cependant, dans mon expérience, ils partagent beaucoup de la même fonctionnalité. Vous pourriez être en mesure d'obtenir la taille d'un seau en utilisant le client mais je n'ai pas trouvé d'autre moyen similaire à celui-ci.

1 votes

Je répertorie les objets dans mon chemin de cette manière: s3_resource = boto3.resource('s3') source_bucket_obj = s3_resource.Bucket(source_bucket) source_objects = source_bucket_obj.objects.filter(Prefix=source_key) Dis-tu que cela va répertorier tous les fichiers, même s'ils sont plus de 1000?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X