web-dev-qa-db-ja.com

boto3コレクションのサイズを取得するにはどうすればよいですか?

私が使用している方法は、コレクションをリストに変換し、長さをクエリすることです。

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

ただし、これによりコレクション全体が解決され、最初にコレクションを使用する利点がなくなります。これを行うより良い方法はありますか?

20

すべてのオブジェクトをリストせずにバケット内のキーの数を取得する方法はありません。これはAWS S3の制限です( https://forums.aws.Amazon.com/thread.jspa?messageID=164220を参照)。 )。

オブジェクトサマリー(HEAD)を取得しても実際のデータは取得されないため、比較的安価な操作であり、リストを破棄するだけの場合は、次のようにすることができます。

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

リストを作成しなくても、オブジェクトの数がわかります。

26
AChampion

同様の質問 から借用し、バケット+プレフィックスからオブジェクトキーの完全なリストを取得する1つのオプションは、 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))
2
doremi

私の使用例では、フォルダーが空かどうかを知る必要がありました。

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

これで、フォルダが空かどうかを確認できました。 S3コンソールで手動で作成されたフォルダーは、リソース自体としてカウントされる可能性があることに注意してください。この場合、上記の長さが1より大きい場合、S3「フォルダ」は空です。

0
andersan