Principiante4 min de lectura

Paginación en DynamoDB

DynamoDB nunca devuelve «todos» los resultados en una sola llamada. Un Query o un Scan devuelve como máximo 1 MB de datos, y luego te entrega un LastEvaluatedKey desde el que reanudar. Paginar bien significa iterar sobre esa clave —no sobre un contador.

El bucle

let key;
do {
  const out = await client.send(new QueryCommand({...params, ExclusiveStartKey: key}));
  process(out.Items);
  key = out.LastEvaluatedKey;
} while (key);

Cuando LastEvaluatedKey es undefined, has llegado al final. Pásalo de vuelta como ExclusiveStartKey para obtener el siguiente fragmento.

El flujo de control es un único bucle que solo termina cuando falta una clave:

presentabsentQuery / ScanProcess ItemsLastEvaluatedKey?Set ExclusiveStartKeyDone

Cada pasada reanuda desde la clave devuelta o se detiene —no hay contador.

Limit no es un tamaño de página

Limit limita cuántos Items evalúa DynamoDB, no cuántos devuelve después de un FilterExpression. Una consulta con Limit: 25 detrás de un filtro puede devolver 3 Items y aún así entregarte un LastEvaluatedKey —debes seguir paginando hasta que la clave esté vacía, incluso cuando una página parezca corta. Un LastEvaluatedKey no vacío tampoco promete nunca más Items coincidentes; solo una clave ausente demuestra que has llegado al final.

Deja que el SDK pagine

Ambos SDK envuelven el bucle anterior para que puedas iterar las páginas directamente:

// AWS SDK for JavaScript v3
import {paginateQuery} from '@aws-sdk/lib-dynamodb';
for await (const page of paginateQuery({client}, params)) {
  process(page.Items);
}
# boto3
paginator = client.get_paginator('query')
for page in paginator.paginate(**params):
    process(page['Items'])

Sin números de página

DynamoDB no tiene un recuento total ni acceso aleatorio a las páginas —no puedes saltar a la «página 7» ni retroceder sin reproducir los cursores. Diseña las interfaces en torno al scroll infinito / «cargar más», no en torno a páginas numeradas. (Una consulta con Select: 'COUNT' sigue leyendo —y facturando— cada Item coincidente para contarlos.)

Cursores sin estado para las API

LastEvaluatedKey no es más que los atributos de clave del último Item. Codifícalo en base64 y entrégaselo a los clientes como un nextToken opaco; decodifícalo de vuelta a ExclusiveStartKey en la siguiente solicitud. Sin estado de cursor en el servidor.

Ese token es DynamoDB-JSON —examínalo o créalo a mano con el conversor de DynamoDB-JSON. Y si estás paginando para sortear un Scan, eso suele ser una señal de que deberías añadir un índice en su lugar.

Prueba DynoTable para paginar visualmente los resultados de una consulta, con el cursor controlado por ti.

Actualizado