如何获得boto3 Collection的大小?

Rah*_*aki 17 python collections boto3

我一直在使用的方法是将Collection转换为List并查询长度:

s3 = boto3.resource('s3')
bucket = s3.Bucket('my_bucket')
size = len(list(bucket.objects.all()))
Run Code Online (Sandbox Code Playgroud)

然而,这迫使整个系列的解决方案并且首先避免了使用Collection的好处.有一个更好的方法吗?

ACh*_*ion 28

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

获取对象摘要(HEAD)不会获得实际数据,因此应该是相对便宜的操作,如果您只是丢弃列表,那么您可以执行以下操作:

size = sum(1 for _ in bucket.objects.all())
Run Code Online (Sandbox Code Playgroud)

这将为您提供没有构建列表的对象数量.

  • 如果您对某个键前缀或“文件夹”感兴趣,这会很有帮助 `size = sum(1 for _ in bucket.objects.filter(Prefix='my_key_prefix/'))` (2认同)

dor*_*emi 6

借用类似的问题,从存储桶 + 前缀检索对象键的完整列表的一种选择是使用带有 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))
Run Code Online (Sandbox Code Playgroud)