Query do DynamoDB em Python (boto3)
O paginador query do boto3 é a razão de esta página ser curta: ele esconde o LastEvaluatedKey por completo. Ele também esconde um número que você provavelmente queria, e é essa a parte que vale conhecer antes de confiar nele. Para saber quando recorrer ao query, veja Query vs. Scan.
Código
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")O paginador não soma a sua conta
Contra um fixture de 600 músicas, cada uma com ~3,9 KB e todas sob Artist = "Arturo Sandoval", o laço produz três páginas: 271, 271 e 58 itens, custando 128,5, 128,5 e 27,5 unidades de leitura. Peça ao mesmo paginador um resultado único e mesclado e você recebe isto:
build_full_result() -> Items 600 Count 600 ScannedCount 600
ConsumedCapacity.CapacityUnits 128.5Count e ScannedCount foram somados. ConsumedCapacity não — ele é o número da primeira página, e o total real era 284,5. A configuração do paginador de DynamoDB do botocore é explícita sobre o porquê: Count e ScannedCount estão listados como result keys, e ConsumedCapacity como uma non-aggregate key. Se você está registrando capacidade a partir do build_full_result(), está subnotificando a leitura de uma partição inteira em mais da metade.
Os dicts por página no laço for page in paginator.paginate(...) acima são respostas cruas, então somar page["ConsumedCapacity"]["CapacityUnits"] por conta própria te dá os honestos 284,5.
O Limit que te custa 58 idas e voltas extras
Limit é um parâmetro válido de query, então o paginate() o aceita, e ele não é o parâmetro que os usuários de Python esperam:
paginate(..., Limit=10) -> 61 pages, 10 items each
paginate(...) -> 3 pagesEle limita itens por requisição, não no total, então o paginador obedientemente faz 61 chamadas HTTP para buscar os mesmos 600 itens. Para limitar o total, use PaginationConfig={"MaxItems": 10}; o PaginationConfig["PageSize"] é o botão que mapeia para o Limit.
Medido em 2026-07-28 contra o DynamoDB Local (amazon/dynamodb-local) com boto3 1.43.58 no CPython 3.14.6.
Explicação
- O cliente fala DynamoDB JSON nas duas direções. Os valores entram como
{"S": "Arturo Sandoval"}eYearvolta como{"N": "1994"}. A API de resource (boto3.resource("dynamodb").Table(...).query) converte nos dois sentidos e te entregaDecimal('1994')— o que é correto para dinheiro e surpreendente na primeira vez que ele se recusa a somar com umfloat. Key("Artist").eq(...)pertence somente à API de resource. Passá-lo ao cliente gera erro antes de a requisição sair:ParamValidationError: Invalid type for parameter KeyConditionExpression ... valid types: <class 'str'>. O cliente quer a string de expressão que esta página monta.- A condição de chave é uma igualdade mais no máximo uma comparação de chave de classificação (
=,<,<=,>,>=,BETWEEN,begins_with). Coloque qualquer outra coisa em umaFilterExpression, que o boto3 repassa direto e o DynamoDB aplica depois da leitura.ScanIndexForward=Falseinverte a ordem eIndexName="..."redireciona para um índice.
Faça isso visualmente
O DynamoDB Expression Builder escreve a condição de chave e o mapa tipado de ExpressionAttributeValues como Python pronto para o boto3, que é justamente a parte que dá errado quando você digita {"N": 2010} em vez de {"N": "2010"}.
Para apontar a mesma consulta às suas próprias tabelas a partir de um formulário de condição de chave e ler os resultados em uma grade paginada, baixe o DynoTable.
Guias relacionados
- Query vs. Scan — por que o
queryé o padrão certo. - Expressões de condição de chave — todos os operadores legais de chave de partição/classificação.
- "Query condition missed key schema element" — a condição de chave nomeia o atributo errado ou pula a chave de partição.
- "Query key condition not supported" — um operador que a condição de chave não pode usar, como contains ou uma segunda condição de chave de classificação.