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.5

Count 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 pages

Limita 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"} y Year vuelve como {"N": "1994"}. La API de resource (boto3.resource("dynamodb").Table(...).query) convierte en los dos sentidos y te entrega Decimal('1994') — lo correcto para el dinero y sorprendente la primera vez que se niega a sumarse a un float.
  • 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 una FilterExpression, que boto3 pasa tal cual y DynamoDB aplica después de la lectura. ScanIndexForward=False invierte el orden y IndexName="..." 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

Referencias

Construye esta solicitud visualmente

Compón esta operación en el Generador de consultas de DynamoDB gratuito —condición de clave, filtro, índice, Limit, orden de clasificación y un bucle de paginación— y cópiala de vuelta como un programa ejecutable para SDK v3, CLI o boto3.

Abrir el Generador de consultas de DynamoDB

Trabaja con DynamoDB sin la Consola

Un cliente de escritorio rápido para DynamoDB que ejecuta el SQL real que DynamoDB no puede — JOINs, GROUP BY, agregaciones — con edición visual y un agente de IA con tus propias claves de Bedrock.

Prueba gratuita de 30 días, sin tarjeta — después, el plan Free sin límite de tiempo.