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 indexes

Handler 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

  • IndexName tidak menggantikan TableName. Keduanya masuk dalam panggilan yang sama, dan KeyConditionExpression menyebut 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 daftar INCLUDE); menurut API reference, "global secondary index queries cannot fetch attributes from the parent table". Atribut yang hilang berarti get_item susulan 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 IndexName yang sama: table.query(IndexName="AlbumTitle-index", KeyConditionExpression=Key("AlbumTitle").eq("Danzon")), dengan nilai Python native masuk dan Decimal keluar.
  • 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

Referensi

Bangun request ini secara visual

Susun operasi ini di DynamoDB Query Builder gratis — key condition, filter, index, Limit, urutan sortir, dan loop paginasi — lalu salin kembali sebagai program SDK v3, CLI, atau boto3 yang bisa dijalankan.

Buka DynamoDB Query Builder

Bekerja dengan DynamoDB tanpa Console

Klien desktop DynamoDB yang cepat dan menjalankan SQL sungguhan yang tidak bisa dijalankan DynamoDB — JOINs, GROUP BY, agregasi — dengan editing visual dan agen AI pada kunci Bedrock milik Anda sendiri.

Uji coba gratis 30 hari, tanpa kartu kredit — lalu paket Free tanpa batas waktu.