S3 バケットから、数テラのデータをダウンロードしていて、ハマりました。
AWS の 関数、list_objects_v2() は、1000件までしかオブジェクトを取得できないという問題があるようでした。
https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
これを回避するには、1000件ごとに、Continuationtoken を渡してやる必要があるようです。
結果的には、普通に以下のコマンドでダウンロードできました。内部的に、Continuationtoken を渡しているようです。
# aws s3 sync s3://<bucket_name> f:\<folder_name>
試しに、Python スクリプトを作成して今回は Windows11 で実行してみましたができていたようでした。
import boto3
import os
s3_client = boto3.client('s3')
def download_dir():
"""
params:
- prefix: pattern to match in s3
- local: local path to folder in which to place files
- bucket: s3 bucket with target contents
- client: initialized s3 client object
"""
local='.\<folder_name>'
bucket='<bucket_name>'
prefix=''
keys = []
dirs = []
next_token = ''
base_kwargs = {
'Bucket':bucket,
'Prefix':prefix,
}
while next_token is not None:
kwargs = base_kwargs.copy()
if next_token != '':
kwargs.update({'ContinuationToken': next_token})
results = client.list_objects_v2(**kwargs)
contents = results.get('Contents')
for i in contents:
k = i.get('Key')
if k[-1] != '/':
keys.append(k)
else:
dirs.append(k)
next_token = results.get('NextContinuationToken')
for d in dirs:
dest_pathname = os.path.join(local, d)
if not os.path.exists(os.path.dirname(dest_pathname)):
os.makedirs(os.path.dirname(dest_pathname))
for k in keys:
dest_pathname = os.path.join(local, k)
if not os.path.exists(os.path.dirname(dest_pathname)):
os.makedirs(os.path.dirname(dest_pathname))
client.download_file(bucket, k, dest_pathname)
if __name__ == "__main__":
client = boto3.client('s3')
resource = boto3.resource('s3')
download_dir()
(参考)
https://newbedev.com/boto3-to-download-all-files-from-a-s3-bucket