DynamoDB Query en Python (boto3)
El paginador query de boto3 es la razón de que esta página sea corta: esconde LastEvaluatedKey por completo. También esconde un número que probablemente querías, y esa es la parte que conviene saber antes de confiar en él. Para saber cuándo recurrir a query, mira 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")El paginador no te suma la factura
Contra un conjunto de prueba de 600 canciones, cada una de ~3,9 KB y todas bajo Artist = "Arturo Sandoval", el bucle produce tres páginas: 271, 271 y 58 Items, que cuestan 128,5, 128,5 y 27,5 unidades de lectura. Pídele al mismo paginador un único resultado combinado y obtienes esto:
build_full_result() -> Items 600 Count 600 ScannedCount 600
ConsumedCapacity.CapacityUnits 128.5Count y ScannedCount se sumaron. ConsumedCapacity no — es la cifra de la primera página, y el total real era 284,5. La configuración del paginador de DynamoDB en botocore es explícita sobre por qué: Count y ScannedCount están listados como claves de resultado, y ConsumedCapacity como clave no agregable. Si registras la capacidad a partir de build_full_result(), estás subestimando en más de la mitad una lectura de partición completa.
Los diccionarios por página del bucle for page in paginator.paginate(...) de arriba son respuestas en crudo, así que sumar tú mismo page["ConsumedCapacity"]["CapacityUnits"] da el honesto 284,5.
El Limit que te cuesta 58 viajes de ida y vuelta extra
Limit es un parámetro válido de query, así que paginate() lo acepta, y no es el parámetro que los usuarios de Python esperan:
paginate(..., Limit=10) -> 61 pages, 10 items each
paginate(...) -> 3 pagesLimita los Items por petición, no en total, así que el paginador hace obedientemente 61 llamadas HTTP para traer los mismos 600 Items. Para limitar el total, usa PaginationConfig={"MaxItems": 10}; PaginationConfig["PageSize"] es el mando que se corresponde con Limit.
Medido el 2026-07-28 contra DynamoDB Local (amazon/dynamodb-local) con boto3 1.43.58 sobre CPython 3.14.6.
Explicación
- El cliente habla DynamoDB JSON en ambas direcciones. Los valores entran como
{"S": "Arturo Sandoval"}yYearvuelve como{"N": "1994"}. La API de resource (boto3.resource("dynamodb").Table(...).query) convierte en los dos sentidos y te entregaDecimal('1994')— lo correcto para el dinero y sorprendente la primera vez que se niega a sumarse a unfloat. Key("Artist").eq(...)pertenece solo a la API de resource. Pasárselo al cliente lanza un error antes de que salga la petición:ParamValidationError: Invalid type for parameter KeyConditionExpression ... valid types: <class 'str'>. El cliente quiere la cadena de expresión que construye esta página.- La condición de clave es una igualdad más como mucho una comparación sobre la clave de ordenación (
=,<,<=,>,>=,BETWEEN,begins_with). Cualquier otra cosa va en unaFilterExpression, que boto3 pasa tal cual y DynamoDB aplica después de la lectura.ScanIndexForward=Falseinvierte el orden yIndexName="..."redirige a un índice.
Hazlo visualmente
El DynamoDB Expression Builder escribe la condición de clave y el mapa tipado de ExpressionAttributeValues como Python listo para boto3, que es justo la parte que se tuerce cuando escribes {"N": 2010} en vez de {"N": "2010"}.
Para apuntar esa misma consulta a tus propias tablas desde un formulario de condición de clave y leer los resultados en una cuadrícula paginada, descarga DynoTable.
Guías relacionadas
- Query vs. Scan — por qué
queryes el valor por defecto correcto. - Expresiones de condición de clave — todos los operadores legales de clave de partición y de ordenación.
- "Query condition missed key schema element" — la condición de clave nombra el atributo equivocado o se salta la clave de partición.
- "Query key condition not supported" — un operador que la condición de clave no puede usar, como contains o una segunda condición sobre la clave de ordenación.