【AWS】boto3 API / list_objects_v2 の 使用上の注意 と その対策

■ はじめに

https://dk521123.hatenablog.com/entry/2019/10/21/230004

の続き。
今回は、list_objects_v2 の 使用上の注意 を扱う

使用上の注意

【1】1000件ずつ取得する
【2】配下のフォルダ・ファイル全てを取得してしまう
【3】prefix で「xxxx/」と「xxxx」だと結果が異なる

【1】1000件ずつ取得する

* 必ずしも全件じゃない
* NextContinuationTokenを受け取り、
   ContinuationToken にセットし、次の1000件を取得する

サンプル

import boto3

def get_list(bucket_name, prefix):
  s3_client = boto3.client('s3')

  return_values = []
  next_token = None
  while True:
    if next_token is None:
      response = s3_client.list_objects_v2(
        Bucket=bucket_name, Prefix=prefix)
    else:
      response = s3_client.list_objects_v2(
        Bucket=bucket_name, Prefix=prefix, ContinuationToken=next_token)

    for content in response['Contents']:
      return_values.append(content['Key'])

      if 'NextContinuationToken' in response:
        next_token = response['NextContinuationToken']
      else:
        next_token = None
        break

  return return_values

参考文献

https://tgctkkz.com/741

【2】配下のフォルダ・ファイル全てを取得してしまう

import boto3

s3_client = boto3.client('s3')

response = s3_client.list_objects_v2(
    Bucket='bucket-name',
    Prefix='folder-a/',
)

print(response)

フォルダ構成例

backet_name
 + folder-a <-- Prefix にここを指定
    + folder-a1 << 表示対象
        + a1-0001.txt << 表示対象 ★配下の配下まで表示してしまう★
        + a1-0002.txt << 表示対象 ★配下の配下まで表示してしまう★
        + folder-a1_1 << 表示対象 ★配下の配下まで表示してしまう★
            + a1_1-0001.txt << 表示対象 ★配下の配下まで表示してしまう★
    + folder-a2 << 表示対象
        + a2-0001.txt << 表示対象 ★配下の配下まで表示してしまう★
    + a-0001.txt << 表示対象
    + a-0002.txt << 表示対象
 + folder-aa
    + aa-0001.txt
 + folder-b
    + folder-b1
        + b1-0001.txt
 + folder-c

配下のファイルのみを取得するには...

解決案1
https://www.ppoohh.info/post-484/

より抜粋
~~~~
フォルダや下の階層まで取得する必要がなければ
「Delimiter='/'」を指定すればオブジェクトのみが取得できます
~~~~

※ 注意
Boto3のバージョンによっては、意図しないうごきになるかも。。。

サンプル

import boto3

s3_client = boto3.client('s3')

response = s3_client.list_objects_v2(
    Bucket='bucket-name',
    Prefix='folder-a/',
    Delimiter='/'
)

【3】prefix で「xxxx/」と「xxxx」だと結果が異なる

例1

import boto3

s3_client = boto3.client('s3')

response = s3_client.list_objects_v2(
    Bucket='bucket-name',
    Prefix='folder-a',
)

フォルダ構成

backet_name
 + folder-a <-- Prefix にここを指定
    + folder-a1 << 表示対象
        + a1-0001.txt << 表示対象
        + a1-0002.txt << 表示対象
        + folder-a1_1 << 表示対象
            + a1_1-0001.txt << 表示対象
    + folder-a2 << 表示対象
        + a2-0001.txt << 表示対象
    + a-0001.txt << 表示対象
    + a-0002.txt << 表示対象
 + folder-aa << 表示対象 ★folder-aXも対象になってしまう★
    + aa-0001.txt << 表示対象
 + folder-b
    + folder-b1
        + b1-0001.txt
 + folder-c

例2

import boto3

s3_client = boto3.client('s3')

response = s3_client.list_objects_v2(
    Bucket='bucket-name',
    Prefix='folder-a/',
)

フォルダ構成

backet_name
 + folder-a <-- Prefix にここを指定
    + folder-a1 << 表示対象
        + a1-0001.txt << 表示対象
        + a1-0002.txt << 表示対象
        + folder-a1_1 << 表示対象
            + a1_1-0001.txt << 表示対象
    + folder-a2 << 表示対象
        + a2-0001.txt << 表示対象
    + a-0001.txt << 表示対象
    + a-0002.txt << 表示対象
 + folder-aa
    + aa-0001.txt
 + folder-b
    + folder-b1
        + b1-0001.txt
 + folder-c

関連記事

Amazon S3 ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2017/03/06/212734
Amazon S3Python boto3でS3を操作する ~
https://dk521123.hatenablog.com/entry/2019/10/21/230004
Amazon S3AWS CLIでS3を操作する ~
https://dk521123.hatenablog.com/entry/2017/04/01/235355
Amazon S3 ~ アクセス制御 ~
https://dk521123.hatenablog.com/entry/2020/09/29/165636
EC2内のログを CloudWatch Logs で管理する
https://dk521123.hatenablog.com/entry/2018/02/20/220305
CloudWatch Logs に関する あれこれ
https://dk521123.hatenablog.com/entry/2018/05/01/215925