Python (boto3) での DynamoDB GSI のクエリ

グローバルセカンダリインデックスのクエリは、通常の query にパラメーターを1つ加えたものです: IndexName。キー条件はテーブルのキーではなくインデックスのキーを対象とします。ここでは AlbumTitle-index によってアルバムで曲を取得できます。これは、ベーステーブル(Artist + SongTitle)ではスキャンなしには対応できないアクセスパターンです。

Code

import boto3

client = boto3.client("dynamodb")

paginator = client.get_paginator("query")

items = []
for page in paginator.paginate(
    TableName="Music",
    IndexName="AlbumTitle-index",
    KeyConditionExpression="#hashKey = :hashKeyValue",
    ExpressionAttributeNames={"#hashKey": "AlbumTitle"},
    ExpressionAttributeValues={":hashKeyValue": {"S": "Danzon"}},
):
    items.extend(page["Items"])

print(f"Found {len(items)} songs on the album")

Explanation

  • IndexName — クエリする GSI を指定します(TableName は依然として必須)。KeyConditionExpressionインデックスのパーティション(および任意でソート)キー — ここでは AlbumTitle — を、テーブルクエリと同じ演算子で使います。
  • 結果整合性のみ — GSI はベーステーブルから非同期にレプリケーションされます。GSI クエリで ConsistentRead=True を渡してもアップグレードされず、ValidationException を発生させます。(ローカルセカンダリインデックスは強い整合性をサポートします。)
  • 投影された属性のみ取得できる — GSI クエリはインデックスが投影するもの(ALLKEYS_ONLY、または INCLUDE で列挙された属性)を返し、残りをベーステーブルから取得することはできません。投影されていない属性が必要ですか?テーブルキーに対する get_item で追跡するか、投影を広げましょう。
  • GSI ではキーは一意ではない — 多くのアイテムが同じインデックスキーを共有でき、インデックスキー属性を持たないアイテムは単に現れません(これがスパースインデックスのパターンです)。
  • ページネーションclient.get_paginator("query") は、テーブルクエリとまったく同じように各ページで LastEvaluatedKey を追跡します。各 pageItems リストを持ちます。
  • リソースAPI では、同じクエリはネイティブな Python 値を使った table.query(IndexName="AlbumTitle-index", KeyConditionExpression=Key("AlbumTitle").eq("Danzon")) です。

Do it visually

DynamoDB Expression Builder はインデックスクエリのためにキー条件 + 名前/値のマップを構築し、実行可能な boto3 コードをコピーします。

テーブルのインデックスを参照し、フォームから GSI クエリを実行するには(ページネーションされたグリッド、コードとしてコピー)、DynoTable をダウンロードしてください。

References

最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。

このリクエストをビジュアルに組み立てる

この操作を無料の DynamoDB クエリビルダーで組み立て — キー条件、フィルタ、インデックス、Limit、ソート順、ページネーションループ — 実行可能な SDK v3・CLI・boto3 のプログラムとしてコピーして戻れます。

DynamoDB クエリビルダーを開く

Console なしで DynamoDB を扱う

DynoTable は DynamoDB 向けの高速なデスクトップクライアントです — テーブルを閲覧し、SQL スタイルのクエリを実行し、アイテムをローカルで編集できます。