Débutant4 min de lecture

Pagination dans DynamoDB

DynamoDB ne renvoie jamais « tous » les résultats en un seul appel. Un Query ou un Scan renvoie au plus 1 MB de données, puis te tend un LastEvaluatedKey pour reprendre. Bien paginer, c'est boucler sur cette clé — pas sur un compteur.

Comment fonctionne la pagination dans DynamoDB ?

Un Query ou un Scan renvoie au plus 1 MB par appel, puis te retourne un LastEvaluatedKey. Pour paginer, tu passes cette clé comme ExclusiveStartKey de l'appel suivant et tu boucles jusqu'à ce que DynamoDB ne renvoie plus de clé. Il n'y a ni numéros de page, ni décompte total, et Limit plafonne les items évalués — pas les items renvoyés.

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

Quand LastEvaluatedKey vaut undefined, tu as atteint la fin. Repasse-la comme ExclusiveStartKey pour récupérer la tranche suivante.

Le flux de contrôle est une seule boucle qui ne sort que sur une clé absente :

presentabsentQuery / ScanProcess ItemsLastEvaluatedKey?Set ExclusiveStartKeyDone

Chaque passe reprend depuis la clé renvoyée ou s'arrête — il n'y a pas de compteur.

Limit n'est pas une taille de page

Limit plafonne le nombre d'items que DynamoDB évalue, pas le nombre qu'il renvoie après un FilterExpression. Une requête Limit: 25 derrière un filtre peut renvoyer 3 items et te tendre malgré tout un LastEvaluatedKey — tu dois continuer à paginer tant que la clé n'est pas vide, même quand une page paraît courte. Un LastEvaluatedKey non vide ne promet jamais plus d'items correspondants non plus ; seule une clé absente prouve que tu as atteint la fin.

Laisse le SDK paginer

Les deux SDK enveloppent la boucle ci-dessus pour que tu puisses itérer les pages directement :

// 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'])

Pas de numéros de page

DynamoDB n'a ni décompte total, ni accès aléatoire aux pages — tu ne peux pas sauter à la « page 7 » ni revenir en arrière sans rejouer les curseurs. Conçois les UI autour du défilement infini / « charger plus », pas de pages numérotées. (Une requête Select: 'COUNT' lit — et facture — quand même chaque item correspondant pour les compter.)

Curseurs sans état pour les API

LastEvaluatedKey n'est que les attributs de clé du dernier item. Encode-le en base64 et tends-le aux clients comme un nextToken opaque ; redécode-le en ExclusiveStartKey à la requête suivante. Aucun état de curseur côté serveur.

Ce token est du DynamoDB-JSON — inspecte-le à l'œil ou fabrique-en un à la main avec le convertisseur DynamoDB-JSON. Et si tu pagines pour contourner un Scan, c'est en général le signe qu'il faut plutôt ajouter un index.

Pour ne pas écrire la boucle du tout, le générateur de requêtes compose la requête Query/Scan complète et émet un programme SDK v3, CLI ou boto3 exécutable — boucle de pagination comprise.

Essaie DynoTable pour parcourir les résultats de requête visuellement, avec le curseur suivi pour toi.

Mis à jour