2015-09-05 144 views
9

我一直使用的方式是集合转换成一个列表,查询长度:如何获得boto3集合的大小?

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

然而,整个集合的这股势力的分辨率和消除在第一时间使用收集的好处。有一个更好的方法吗?

回答

17

如果没有列出所有对象(这是AWS S3的限制)(请参阅https://forums.aws.amazon.com/thread.jspa?messageID=164220),则无法获取存储桶中密钥的计数。

获取对象摘要(HEAD)没有得到实际的数据,所以应该是一种相对廉价的操作,如果你是刚刚丢弃的名单,那么你可以这样做:

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

,这将给你的没有构建列表的对象的数量。

0

借用similar question,从桶+前缀检索对象键的完整列表的一个选项是使用递归与list_objects_v2方法。

此方法将一次递归检索对象键列表,1000个键。

list_objects_v2的每个请求都使用StartAfter参数继续列出上一个请求中最后一个键后面的键。

import boto3 

if __name__ == '__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))