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

■ はじめに

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

の続き。

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

目次

【1】デフォルト だと 1000件ずつ取得する
 0)Paginators について
 1)サンプル
【2】配下のフォルダ・ファイル全てを取得してしまう
 1)サンプル
 2)フォルダ構成例
 3)配下のファイルのみを取得するには
【3】prefix で「xxxx/」と「xxxx」だと結果が異なる
 1)サンプル

【1】デフォルト だと 1000件ずつ取得する

* boto3 の list_objects_v2 でS3パスの一覧を取得した際に
 デフォルト だと 1000件を超える場合は、1000件で区切られて
 続きは自分で実装して取得しに行かなければならない
* 1000件を超える場合、サンプルのように
 NextContinuationTokenを受け取り、
   ContinuationToken にセットし、次の1000件を取得する
 => 一般的な用語で「ページネーション」という

0)Paginators について

* 後から気づいたのだが、Paginators って仕組みがあり
 今回、紹介するサンプルより簡潔に書ける
 => 詳細は、以下の関連記事を参照のこと

boto3 ~ Paginators ~
https://dk521123.hatenablog.com/entry/2024/09/21/015013

1)サンプル

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】配下のフォルダ・ファイル全てを取得してしまう

1)サンプル

import boto3

s3_client = boto3.client('s3')

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

print(response)

2)フォルダ構成例

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

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

解決案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)サンプル

例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
boto3 ~ Paginators ~
https://dk521123.hatenablog.com/entry/2024/09/21/015013
EC2内のログを CloudWatch Logs で管理する
https://dk521123.hatenablog.com/entry/2018/02/20/220305
CloudWatch Logs に関する あれこれ
https://dk521123.hatenablog.com/entry/2018/05/01/215925