Python'da (boto3) DynamoDB GSI Sorgulama
Bir GSI sorgusu, normal bir query artı IndexName'dir ve AlbumTitle-index bize şarkıları albüme göre verir — Artist + SongTitle tablo anahtarının karşılayamayacağı bir erişim deseni. Python'da değişen şey hata işlemedir: en yaygın iki indeks hatası boto3'ün farklı katmanlarında başarısız olur ve yalnızca biri istisna sınıfıyla yakalanabilir.
Kod
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 yakalamak şöyle dursun, derlenmez bile
Yukarıdaki sorguya ConsistentRead=True ekleyin; boto3 bunu hem istemci hem de kaynak API'sinde fırlatır:
botocore.exceptions.ClientError: An error occurred (ValidationException) when
calling the Query operation: Consistent reads are not supported on global
secondary indexesAkla gelen işleyici except client.exceptions.ValidationException'dır. Öyle bir şey yoktur:
AttributeError: <botocore.errorfactory.DynamoDBExceptions object> has no
attribute ValidationException. Valid exceptions are: BackupInUseException,
... IndexNotFoundException, ... ProvisionedThroughputExceededException, ...botocore istisna sınıflarını hizmet modelinden üretir ve DynamoDB bunlardan 33 tanesini modeller. ValidationException bir protokol düzeyi hatasıdır ve onlardan biri değildir; dolayısıyla tek güvenilir dallanma kod üzerinedir:
except ClientError as exc:
if exc.response["Error"]["Code"] == "ValidationException":
...Asimetri gerçektir. İndeks adını yanlış yazın, IndexNotFoundException alırsınız — ki o modellenmiştir ve sınıfa göre yakalanabilir. Tutarlılık bayrağını yanlış kullanın, bir string karşılaştırması alırsınız. İkisi de indeks hatasıdır; yalnızca birinin bir türü vardır.
İmleç tablo anahtarını da taşır
Sayfalayıcı LastEvaluatedKey'i saklar, ama bir indekste ne tuttuğunu bilmeye değer. Tek bir albümdeki 300 şarkı üzerinde:
page 1: Count 271 capacity 128.5 LastEvaluatedKey ['AlbumTitle', 'Artist', 'SongTitle']
page 2: Count 29 capacity 14.0 LastEvaluatedKey []Bir GSI anahtarı benzersiz değildir, dolayısıyla indeks anahtarı tek başına okumayı sürdüremez; DynamoDB indeks anahtarını ve temel tablo anahtarını birlikte döndürür. Yalnızca indeks anahtarını saklayan elle yazılmış sayfalama öğeleri tekrarlar ya da atlar.
2026-07-28 tarihinde DynamoDB Local'a (amazon/dynamodb-local) karşı, CPython 3.14.6 üzerinde boto3 1.43.58 ile yeniden üretildi. Hata metni ve anahtar listeleri kütüphanenin kendi çıktısıdır.
Açıklama
IndexName,TableName'in yerine geçmez. İkisi de aynı çağrıya girer veKeyConditionExpression, bir tablo sorgusuyla aynı operatör kümesini kullanarak indeksin bölüm anahtarını (AlbumTitle) adlandırır.- Yalnızca projeksiyonu alırsınız, başka bir şey değil. İndeks neyi projelendiriyorsa onu döndürür (
ALL,KEYS_ONLYya daINCLUDElistesi); API referansına göre "global secondary index queries cannot fetch attributes from the parent table". Eksik bir öznitelik, temel anahtar üzerinde bir sonrakiget_itemçağrısı ya da yeni bir indekste daha geniş bir projeksiyon demektir. - İndeks anahtarı olmayan öğeler hiç görünmez — seyrek indeks deseni.
status = "OPEN"üzerindeki bir indeksi küçük tutar ve bir GSI sorgusunun beklediğinizden azını döndürüp hiçbir şey fırlatmamasının nedeni de budur. - Kaynak API'si aynı
IndexName'i alır:table.query(IndexName="AlbumTitle-index", KeyConditionExpression=Key("AlbumTitle").eq("Danzon"))— girişte yerel Python değerleri, çıkıştaDecimal. - Bir GSI yazması tablo yazmasından sonra iner. Çoğaltma eşzamansızdır, dolayısıyla indekse karşı bir yazma-sonrası-okuma yolu arada bir ıskalar. Onu sıkı bir döngüde yeniden denemek, çoğaltmayı hızlandırmadan kapasite yakar.
Görsel olarak yapın
DynamoDB Expression Builder, indeks anahtar koşulunu ve türlü değer haritasını boto3'e hazır Python olarak yazar — istemcinin ısrar ettiği, kaynak API'sinin ise yasakladığı {"S": ...} sarmalayıcıları dahil.
Aynı indeks sorgusunu bir formdan kendi tablolarınıza yöneltmek ve sonuçları sayfalanmış bir ızgarada okumak için DynoTable'ı indirin.
İlgili örnekler
- Node.js'te DynamoDB GSI sorgulama — AWS SDK v3 ile aynı indeks sorgusu.
- AWS CLI ile DynamoDB GSI sorgulama — kabuktan aynı indeks sorgusu.
- Python'da DynamoDB Query — temel tabloyu sorgulama.
- GSI ile LSI — erişim desenine hangi indeks türü uyar.
- GSI'lar neden nihai tutarlıdır — çoğaltma gecikmesi açıklanıyor.
- "The table does not have the specified index" — indeks adı eşleşmiyor (GSI adları büyük/küçük harfe duyarlıdır).
- "Consistent reads are not supported on global secondary indexes" — tutarlı okuma bayrağı bir GSI'da neden başarısız olur.