如何获取boto3中已过滤对象集合的大小

时间:2018-06-25 21:35:43

标签: python boto3

我已经尝试了以下方法来获取boto3 v1.7.37中s3.Bucket.objectsCollection的len / content_length:

import boto3    
s3 = boto3.resource('s3')
bucket = s3.Bucket('myBucket')
bucketObjects = bucket.objects.filter(Prefix='myPrefix')
if (len(bucketObjects) > 0):
     do_something()
else:
     do_something_else()

不幸的是,这给了我以下错误:

TypeError: object of type 's3.Bucket.objectsCollection' has no len()

我也尝试过bucketobjects.content_length并得到

AttributeError: 's3.Bucket.objectsCollection' object has no attribute 'content_length'

我是否必须遍历列表并计算对象,还是有更好的方法?

2 个答案:

答案 0 :(得分:2)

bucket.objects.filter()(以及大多数其他返回对象集合的高级boto3调用)返回没有确定长度的可迭代对象。这是有意的,因为列表的潜在大小可能非常大。为了防止您的应用程序用尽内存,它们永远不会一次全部加载-因此大小保持未知,直到您实际依次请求每个项目并结束为止。

如果您确定列表很短,请使用bucketObjects = list(bucketObjects)将其全部保存,但最好不要这样做。通过一次阅读来计数:

c=0
for b in bucketObjects: c+=1

(如果您确实需要最大的效率,请尝试使用低级api:client=boto3.client('s3'),并在几次调用中获得列表的大块内容;或者,如果确定它不是太大,则获取整个列表立即;但这很少值得)

答案 1 :(得分:1)

正如Leo K所说bucket.objects.filter返回没有确定长度的可迭代对象。但是您可以使用limit方法来限制迭代。因此,如果您希望检查列表中是否有一项被发现,可以使用以下内容:

results = bucket.objects.filter(Prefix=prefix_filter) if list(results.limit(1)): do_something() else: do_something_else()