2017-10-02 7 views
1

Je tente d'écrire une fonction lambda pour ajouter de nouvelles données à une table DynamoDB. à la lecture des documents à:Comment empêcher l'écrasement d'un élément DynamoDB si une entrée existe déjà

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#put-property La méthode PUT: « Crée un nouvel élément ou remplace un ancien article avec un nouvel élément en déléguant à AWS.DynamoDB.putItem(). »

En plus de faire une vérification d'un objet avant de mettre 'put', y a-t-il un paramètre ou un indicateur pour échouer l'objet existe quand le PUT est tenté?

Je peux voir dans

params -> Expected -> Exists (Bool) 

mais je ne vois aucune documentation sur ce que cela fait.

Quelle serait la meilleure architecture (ou jeûné) pour empêcher l'écrasement d'un élément?

Query the table first and if no item exists then add the item 

ou

Attempt to insert the item and on failure because of duplicate entry report this back? (Is there a way to prevent item overwrite?) 

Répondre

4

Le ConditionExpression peut être utilisé pour vérifier si les valeurs d'attribut clé existe déjà dans le tableau et effectuer l'opération PUT que si les valeurs clés ne sont pas présents dans le tableau.

Lorsque vous exécutez le code ci-dessous, la première fois que l'opération put doit aboutir. Dans la deuxième exécution, l'opération put doit échouer avec "Demande conditionnelle a échoué" exception.

Ma table de films comporte à la fois des touches de partition et de tri. J'ai donc utilisé les deux attributs dans l'expression conditionnelle.

Exemple de code PUT conditionnel: -

var table = "Movies"; 

var year = 1502; 
var title = "The Big New Movie"; 

var params = { 
    TableName:table, 
    Item:{ 
     "yearkey": year, 
     "title": title, 
     "info":{ 
      "plot": "Nothing happens at all.", 
      "rating": 0 
     } 
    }, 
    ConditionExpression: "yearkey <> :yearKeyVal AND #title <> :title", 
    ExpressionAttributeNames: { 
     "#title" : "title" 
    }, 
    ExpressionAttributeValues: { 
     ":yearKeyVal" : year, 
     ":title": {"S": title} 
    } 
}; 

console.log("Adding a new item..."); 
docClient.put(params, function(err, data) { 
    if (err) { 
     console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2)); 
    } else {   
     console.log("Added item:", JSON.stringify(data, null, 2)); 
    } 
}); 

Exception lorsque l'opération de vente est effectuée deuxième fois: -

Unable to add item. Error JSON: { 
    "message": "The conditional request failed", 
    "code": "ConditionalCheckFailedException", 
    "time": "2017-10-02T18:26:26.093Z", 
    "requestId": "7ae3b0c4-3872-478d-908c-94bc9492a43a", 
    "statusCode": 400, 
    "retryable": false, 
    "retryDelay": 0 
} 
+0

Génial, merci beaucoup pour votre information et votre aide! –

0

Je vois que cette question se rapporte au langage JavaScript, de toute façon J'écrirai aussi pour Java (peut-être cela sera utile pour quelqu'un):

DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression(); 
Map<String, ExpectedAttributeValue> expectedAttributes = 
     ImmutableMapParameter.<String, ExpectedAttributeValue>builder() 
       .put("hashKeyAttrName", new ExpectedAttributeValue(false)) 
       .put("rangeKeyAttrName", new ExpectedAttributeValue(false)) 
       .build(); 
saveExpression.setExpected(expectedAttributes); 
saveExpression.setConditionalOperator(ConditionalOperator.AND); 

try { 
    dynamoDBMapper.save(item, saveExpression); 
} catch (ConditionalCheckFailedException e) { 
    e.printStackTrace(); 
} 

ConditionalCheckFailedException sera lancé si nous essayons d'enregistrer un élément avec une paire déjà existante de hashKey et de rangeKey dans DynamoDB.