DynamoDB Query in Python (boto3)
Il paginator query di boto3 è il motivo per cui questa pagina è corta: nasconde del tutto LastEvaluatedKey. Nasconde anche un numero che probabilmente volevi, ed è la parte che vale la pena conoscere prima di fidarti. Per capire quando usare query, vedi Query vs Scan.
Codice
import boto3
client = boto3.client("dynamodb")
paginator = client.get_paginator("query")
items = []
for page in paginator.paginate(
TableName="Music",
KeyConditionExpression="#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)",
ExpressionAttributeNames={"#hashKey": "Artist", "#rangeKey": "SongTitle"},
ExpressionAttributeValues={":hashKeyValue": {"S": "Arturo Sandoval"}, ":rangeKeyValue": {"S": "C"}},
):
items.extend(page["Items"])
print(f"Found {len(items)} items")Il paginator non ti somma la bolletta
Su una fixture di 600 canzoni, ognuna da ~3,9 KB e tutte sotto Artist = "Arturo Sandoval", il loop produce tre pagine: 271, 271 e 58 Item, al costo di 128,5, 128,5 e 27,5 unità di lettura. Chiedi allo stesso paginator un unico risultato unito e ottieni questo:
build_full_result() -> Items 600 Count 600 ScannedCount 600
ConsumedCapacity.CapacityUnits 128.5Count e ScannedCount sono stati sommati. ConsumedCapacity no — è la cifra della prima pagina, e il totale reale era 284,5. La configurazione del paginator DynamoDB di botocore è esplicita sul perché: Count e ScannedCount sono elencati come result key, ConsumedCapacity come non-aggregate key. Se logghi la capacità da build_full_result(), stai sottostimando la lettura di una partizione intera di oltre la metà.
I dizionari per pagina nel loop for page in paginator.paginate(...) qui sopra sono risposte grezze, quindi sommare tu stesso page["ConsumedCapacity"]["CapacityUnits"] dà l'onesto 284,5.
Il Limit che ti costa 58 round trip in più
Limit è un parametro valido di query, quindi paginate() lo accetta, e non è il parametro che gli utenti Python si aspettano:
paginate(..., Limit=10) -> 61 pages, 10 items each
paginate(...) -> 3 pagesLimita gli Item per richiesta, non complessivamente, quindi il paginator fa diligentemente 61 chiamate HTTP per recuperare gli stessi 600 Item. Per limitare il totale usa PaginationConfig={"MaxItems": 10}; PaginationConfig["PageSize"] è la manopola che corrisponde a Limit.
Misurato il 2026-07-28 su DynamoDB Local (amazon/dynamodb-local) con boto3 1.43.58 su CPython 3.14.6.
Spiegazione
- Il client parla DynamoDB JSON in entrambe le direzioni. I valori entrano come
{"S": "Arturo Sandoval"}eYeartorna come{"N": "1994"}. L'API resource (boto3.resource("dynamodb").Table(...).query) converte in entrambi i sensi e ti consegnaDecimal('1994')— che è giusto per il denaro e sorprendente la prima volta che si rifiuta di sommarsi a unfloat. Key("Artist").eq(...)appartiene solo all'API resource. Passarlo al client solleva un errore prima che la richiesta parta:ParamValidationError: Invalid type for parameter KeyConditionExpression ... valid types: <class 'str'>. Il client vuole la stringa dell'espressione che questa pagina costruisce.- La key condition è un'uguaglianza più al massimo un confronto sulla chiave di ordinamento (
=,<,<=,>,>=,BETWEEN,begins_with). Metti tutto il resto in unaFilterExpression, che boto3 passa direttamente e DynamoDB applica dopo la lettura.ScanIndexForward=Falseinverte l'ordine,IndexName="..."punta la query a un indice.
Fallo visivamente
Il DynamoDB Expression Builder scrive la key condition e la mappa tipizzata ExpressionAttributeValues come Python pronto per boto3, che è la parte che va storta quando scrivi {"N": 2010} invece di {"N": "2010"}.
Per puntare la stessa query alle tue tabelle da un form di key condition e leggere i risultati in una griglia paginata, scarica DynoTable.
Guide correlate
- Query vs Scan — perché
queryè il default giusto. - Key condition expressions — ogni operatore legale su chiave di partizione e di ordinamento.
- "Query condition missed key schema element" — la key condition nomina l'attributo sbagliato o salta la chiave di partizione.
- "Query key condition not supported" — un operatore che la key condition non può usare, come contains o una seconda condizione sulla chiave di ordinamento.