Query GSI DynamoDB di Python (boto3)
Query GSI adalah query biasa plus IndexName, dan AlbumTitle-index memberi kita lagu berdasarkan album, sebuah pola akses yang tak bisa dilayani key tabel Artist + SongTitle. Yang berubah di Python adalah penanganan error: dua kesalahan index yang paling umum gagal di lapisan boto3 yang berbeda, dan hanya satu di antaranya yang bisa ditangkap berdasarkan kelas exception.
Kode
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")except ValidationException tidak akan compile, apalagi menangkap
Tambahkan ConsistentRead=True pada query di atas dan boto3 melempar ini, baik di API client maupun API resource:
botocore.exceptions.ClientError: An error occurred (ValidationException) when
calling the Query operation: Consistent reads are not supported on global
secondary indexesHandler yang paling jelas adalah except client.exceptions.ValidationException. Ia tidak ada:
AttributeError: <botocore.errorfactory.DynamoDBExceptions object> has no
attribute ValidationException. Valid exceptions are: BackupInUseException,
... IndexNotFoundException, ... ProvisionedThroughputExceededException, ...botocore menghasilkan kelas exception dari service model, dan DynamoDB memodelkan 33 di antaranya. ValidationException adalah error tingkat protokol dan bukan salah satunya, jadi satu-satunya percabangan yang andal adalah pada kodenya:
except ClientError as exc:
if exc.response["Error"]["Code"] == "ValidationException":
...Asimetrinya nyata. Salah ketik nama index dan Anda mendapat IndexNotFoundException, yang memang dimodelkan dan bisa ditangkap berdasarkan kelas. Salah memakai flag konsistensi dan yang Anda dapat adalah perbandingan string. Keduanya error index; hanya satu yang punya tipe.
Kursornya membawa key tabel juga
Paginator menyembunyikan LastEvaluatedKey, tetapi ada gunanya tahu apa isinya pada sebuah index. Atas 300 lagu dalam satu album:
page 1: Count 271 capacity 128.5 LastEvaluatedKey ['AlbumTitle', 'Artist', 'SongTitle']
page 2: Count 29 capacity 14.0 LastEvaluatedKey []Key GSI tidak unik, jadi key index saja tidak bisa melanjutkan pembacaan; DynamoDB mengembalikan key index dan key tabel dasar bersama-sama. Paginasi buatan tangan yang hanya menyimpan key index akan mengulang atau menjatuhkan item.
Direproduksi 2026-07-28 terhadap DynamoDB Local (amazon/dynamodb-local) dengan boto3 1.43.58 pada CPython 3.14.6. Teks error dan daftar key-nya adalah keluaran library itu sendiri.
Penjelasan
IndexNametidak menggantikanTableName. Keduanya masuk dalam panggilan yang sama, danKeyConditionExpressionmenyebut partition key milik index (AlbumTitle) dengan himpunan operator yang sama seperti query tabel.- Anda mendapat projection-nya dan tidak lebih. Index mengembalikan apa yang ia proyeksikan (
ALL,KEYS_ONLY, atau daftarINCLUDE); menurut API reference, "global secondary index queries cannot fetch attributes from the parent table". Atribut yang hilang berartiget_itemsusulan pada key dasar, atau projection yang lebih lebar pada index baru. - Item yang tidak punya key index tak pernah muncul — pola sparse index. Ia menjaga index atas
status = "OPEN"tetap kecil, dan itu juga sebabnya query GSI bisa mengembalikan lebih sedikit dari yang Anda kira tanpa melempar apa pun. - API resource menerima
IndexNameyang sama:table.query(IndexName="AlbumTitle-index", KeyConditionExpression=Key("AlbumTitle").eq("Danzon")), dengan nilai Python native masuk danDecimalkeluar. - Tulis ke GSI mendarat setelah tulis ke tabel. Replikasinya asinkron, jadi jalur baca-setelah-tulis terhadap index sesekali akan meleset. Mencobanya ulang dalam loop ketat membakar kapasitas tanpa membuat replikasi jadi lebih cepat.
Lakukan secara visual
DynamoDB Expression Builder menuliskan key condition index dan map nilai bertipe sebagai kode Python yang siap dipakai boto3, termasuk pembungkus {"S": ...} yang diwajibkan API client dan dilarang API resource.
Untuk mengarahkan query index yang sama ke tabel Anda sendiri lewat sebuah form dan membaca hasilnya dalam grid berpaginasi, unduh DynoTable.
Contoh terkait
- Query GSI DynamoDB di Node.js — query index yang sama dengan AWS SDK v3.
- Query GSI DynamoDB dengan AWS CLI — query index yang sama dari shell.
- DynamoDB Query di Python — melakukan query pada tabel dasarnya.
- GSI vs. LSI — jenis index mana yang cocok dengan pola aksesnya.
- Mengapa GSI bersifat eventually consistent — lag replikasinya dijelaskan.
- "The table does not have the specified index" — nama index-nya tidak cocok (nama GSI bersifat case-sensitive).
- "Consistent reads are not supported on global secondary indexes" — mengapa flag consistent-read gagal pada sebuah GSI.