Amazon DynamoDB でページ分割を実装するにはどうすればよいですか?

最終更新日: 2022 年 8 月 12 日

Query または Scan オペレーションを使用して Amazon DynamoDB テーブルから項目をフェッチしようとしても、レスポンスは完全な結果を返しません。

解決方法

この問題は、次の状況で発生します。

  • 最初の Scan または Query オペレーションのレスポンスに LastEvaluatedKey が含まれている。
  • 次のリクエストで、このキーを ExclusiveStartKey として使用して、後続のオペレーションを実行しなかった。

この問題は、DynamoDB テーブル用にページ分割を実装することで解決できます。ページ分割とは、前のリクエストが不完全な場合に、後続のリクエストを送信して続行するプロセスです。DynamoDB の Query または Scan オペレーションは、不完全な結果を返し、結果セット全体を取得するために後続のリクエストを必要とする場合があります。これは、DynamoDB が Query または Scan オペレーションの結果をページ分割し、1 回のオペレーションで最大 1 MB のデータを返すためです。これは DynamoDB のハードリミットです。ページ分割では、Scan または Query オペレーションの結果は、サイズが 1 MB 以下のデータのページに分割されます。

結果をページ分割し、一度に 1 ページずつ取得するには、 Scan または Query オペレーションの低レベルの結果をチェックして、結果に LastEvaluatedKey 要素が含まれていないかどうかを確認します。最初のリクエストの残りの結果を取得するには、ExclusiveStartKey パラメータとして LastEvaluatedKey 値を使用して、同じパラメータを持つ別の Scan または Query オペレーションを使用します。結果に LastEvaluatedKey 値が含まれていない場合、取得する項目はありません。

詳細については、「テーブルクエリ結果をページ分割する」および「結果のページ分割」を参照してください。

LastEvaluatedKey を使用して Boto3 でページ分割を実装するには、次のコードサンプルを使用します。

from __future__ import print_function  # Python 2/3 compatibility
import boto3
from botocore.exceptions import ClientError

# Create Client
session = boto3.session.Session()
dynamoDbClient = session.client('dynamodb')

table_name = 'AmazonBins'

# Track number of Items read
item_count = 0

try:
    # Get the first 1MB of data
    response = dynamoDbClient.scan(
        TableName=table_name
    )

except ClientError as error:
    print("Something went wrong: ")
    print(error.response['ResponseMetadata'])

# Track number of Items read
item_count += len(response['Items'])

# Paginate returning up to 1MB of data for each iteration
while 'LastEvaluatedKey' in response:
    try:
        response = dynamoDbClient.scan(
            TableName=table_name,
            ExclusiveStartKey=response['LastEvaluatedKey']
        )
        # Track number of Items read
        item_count += len(response['Items'])

    except ClientError as error:
        print("Something went wrong: ")
        print(error.response['ResponseMetadata'])

print("Total number of items found: {}".format(item_count))

この記事はお役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?