PutItem DynamoDB en Node.js (AWS SDK v3)
PutItem écrit un élément entier et remplace tout élément existant portant la même clé primaire (les actions au niveau de l'élément expliquent en quoi cela diffère d'UpdateItem). Le client v3 envoie directement du DynamoDB JSON, donc Item contient des valeurs { S: … } / { N: … } plutôt que du JavaScript ordinaire.
Code
import {DynamoDBClient, PutItemCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const command = new PutItemCommand({
TableName: 'Music',
Item: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'},
AlbumTitle: {S: 'Danzon'},
Year: {N: '1994'},
Awards: {N: '0'}
},
ConditionExpression: 'attribute_not_exists(#cond0) AND attribute_not_exists(#cond1)',
ExpressionAttributeNames: {
'#cond0': 'Artist',
'#cond1': 'SongTitle'
}
});
try {
await client.send(command);
console.log('Song written');
} catch (err) {
if (err.name === 'ConditionalCheckFailedException') {
console.log('A song with that key already exists — not overwritten');
} else {
throw err;
}
}Explication
err.name est le bon test, et ce n'est pas la seule chose portée par l'erreur. Attraper la condition échouée ci-dessus et afficher l'objet a donné :
err.name ConditionalCheckFailedException
err instanceof Error true
err.message The conditional request failed
err.$metadata.httpStatusCode 400Chaque erreur v3 porte un $metadata avec le code de statut, l'identifiant de requête et le nombre de tentatives, c'est-à-dire ce que tu veux dans une ligne de log. err.name est stable d'un package modulaire à l'autre ; instanceof ConditionalCheckFailedException fonctionne aussi, mais tire la classe comme import de valeur, que les bundlers conservent.
L'erreur peut te remettre l'élément qui a bloqué l'écriture. Ajoute ReturnValuesOnConditionCheckFailure: 'ALL_OLD' à la commande et err.Item arrive renseigné : cinq attributs dans l'exécution ci-dessus, avec Year à {"N":"1994"}. La plupart des handlers « création uniquement » font un GetItem après l'échec pour découvrir ce qui était déjà là. Cet aller-retour est évitable. (ReturnValues: 'ALL_OLD' est le cousin du chemin de succès ; ReturnValues couvre le reste.)
marshall() refuse plus d'entrées que tu ne le crois. Remplacer l'Item typé de cette page par DynamoDBDocumentClient et des objets ordinaires est l'étape suivante habituelle, et @aws-sdk/util-dynamodb est strict par défaut. Trois exceptions réelles, mot pour mot :
{Genre: undefined} Pass options.removeUndefinedValues=true to remove undefined values from map/array/set.
{tags: new Set()} Pass a non-empty set, or options.convertEmptyValues=true.
{n: 9007199254740993} Number 9007199254740992 is greater than Number.MAX_SAFE_INTEGER. Use NumberValue from @aws-sdk/lib-dynamodb.La première est celle qui atteint la production : un champ optionnel undefined plutôt qu'absent lève au moment du marshalling, et removeUndefinedValues: true dans DynamoDBDocumentClient.from(client, {marshallOptions}) est le correctif standard.
Relis la troisième ligne. Le littéral était 9007199254740993 ; le message cite 9007199254740992. JavaScript avait déjà arrondi la valeur avant que le SDK ne la voie, donc le SDK rapporte ce qu'il a reçu. C'est toute la raison pour laquelle DynamoDB transporte N sous forme de chaîne : il conserve 38 chiffres de précision, là où un number JS en tient 15 à 17. Tout ce qui est réellement un identifiant appartient à S, et tout ce qui est réellement un décimal appartient à NumberValue ou à une chaîne que tu formates toi-même.
ConditionExpression coûte de la capacité d'écriture même quand elle dit non. AWS : "if the expression evaluates to false, DynamoDB still consumes write capacity units from the table" (récupéré le 2026-07-28). Une boucle de reprise serrée en création seule est facturée à chaque tentative. Pour l'ordre de grandeur, un put réussi d'un élément d'environ 15 Ko a rapporté "CapacityUnits": 15 ; les écritures s'arrondissent au Ko, pas aux 4 Ko des lectures.
Les alias sont porteurs. #cond0/#cond1 résolvent vers Artist/SongTitle via ExpressionAttributeNames. Les noms en clair fonctionnent jusqu'au jour où l'un d'eux entre en collision avec un mot réservé, et l'expression échoue alors sur un attribut que tu n'as pas touché.
Le faire visuellement
Les règles de marshalling ci-dessus se vérifient plus facilement en voyant les deux formes côte à côte. Le convertisseur DynamoDB JSON gratuit transforme du JSON ordinaire en la forme typée { S: … } et inversement, pour que tu confirmes ce que marshall() aurait produit avant d'envoyer.
Pour écrire et modifier des éléments dans tes propres tables — un formulaire par attribut, des sélecteurs de type, la copie du résultat sous forme de code SDK v3 — télécharge DynoTable.
Guides liés
- Les expressions de condition DynamoDB —
attribute_not_exists, verrouillage optimiste, et plus encore. - Types de données DynamoDB — comment chaque type d'attribut s'écrit.
- DynamoDB ConditionalCheckFailedException — ce que lève la condition « création uniquement » quand l'élément existe déjà.
- DynamoDB ValidationException — le fourre-tout d'un élément ou d'une expression malformés.
Références
- PutItem — Amazon DynamoDB API Reference
- PutItemCommand — AWS SDK for JavaScript v3 Reference
- Capacity unit consumption — Amazon DynamoDB Developer Guide
- Condition expressions — Amazon DynamoDB Developer Guide
- Working with items and attributes — Amazon DynamoDB Developer Guide
Reproduit le 2026-07-28 sur Node v24.18.0 avec @aws-sdk/client-dynamodb 3.1095.0 et @aws-sdk/util-dynamodb 3.996.7, sur DynamoDB Local (amazon/dynamodb-local) sur le port 9000. Les chaînes d'erreur, la forme de l'objet et la mesure de capacité sont de la sortie capturée, copiée telle quelle.