alphanumeric
alphanumeric

Reputation: 19329

Should I use put or update command while adding an item to DynamoDB table

With the year as a Primary Key and the item being:

let item = {

    "year": 2021,
    "title": "Title A"
}

I can go ahead and add it to the DynamoDB using put method:

var AWS = require('aws-sdk');
AWS.config.update({region: "us-east-1"});
const docClient = new DynamoDB.DocumentClient();

var params = {
  TableName: TABLE_NAME,
  Item: item,
  ConditionExpression: "year <> :year",
  ExpressionAttributeValues: {":year": 2021}
};
let promise = docClient.put(params).promise();
promise.then(res => {
  console.log("res:", res);
});

Please note, that I am using ConditionExpression here to assure that the item with the same Primary Key year 2021 does not already exist in the table. If the item exists, I will be getting the error. Otherwise, the item will be added and the empty dictionary is returned.

Instead of using the put method I could get the same functionality using the update command, such as:

let params = {
  TableName: TABLE_NAME,
  Key: {"year": year},
  UpdateExpression: "SET year=:year",
  ExpressionAttributeValues: {":year": year},
  ConditionExpression: "year <> :year"
};  
let promise = docClient.update(params).promise();
promise.then(res => {
  console.log("res:", res);
});

While both put and update commands here do the job well, I tend to like the update command more as it allows me to specify "ALL_NEW" as an argument to ReturnValues parameter (for the put command the option "ALL_NEW" is not available).

Is there any performance drop in using the update command versus the put? Is there any reason why I should be using put instead of update?

Upvotes: 1

Views: 8381

Answers (3)

Mickers
Mickers

Reputation: 1449

The main difference for me is that you can add a ConditionExpression so that you won't accidentally overwrite a key that already exists. Example:

table.update_item(
        Key={
            'ID': '1'
        },
        UpdateExpression='SET #a= :a, #b= :b',
        ConditionExpression='attribute_exists(ID)',
        ExpressionAttributeValues={
            ':a': json.dumps(payload),
            ':b': str(datetime.now())
        },
        ExpressionAttributeNames={
            '#a': 'attribute1',
            '#b': 'attribute2'
        },
        ReturnValues='ALL_NEW'
    )

This example will only perform the update if the item actually exists. You can change it to attribute_not_exists(ID) to insert only if that key does not exist. I feel this gives you better control of when/when not to push data into your table.

Upvotes: 2

jellycsc
jellycsc

Reputation: 12259

In short, in this particular case, there is no difference.

put and update have the same behaviour when the item doesn't exist in the table. Regrading to the throughput difference mentioned by @Daniel Hornik, I disagree. In this case, they both consume the same WCU. Therefore, if you use provisioned throughput for writes, you can expect the same level of throughput.

Upvotes: 0

Daniel Hornik
Daniel Hornik

Reputation: 2521

There is no performance diff, but there is a difference regarding throughput.

  • PutItem - Writes a single item to a table. If an item with the same primary key exists in the table, the operation replaces the item. For calculating provisioned throughput consumption, the item size that matters is the larger of the two.

  • UpdateItem - Modifies a single item in the table. DynamoDB considers the size of the item as it appears before and after the update. The provisioned throughput consumed reflects the larger of these item sizes. Even if you update just a subset of the item's attributes, UpdateItem will still consume the full amount of provisioned throughput (the larger of the "before" and "after" item sizes).

Above quote is from the official AWS docs(see references)

However everything depends what you are doing:

PUT item replace whole entry in DynamoDB. UPDATE can update only single attribute. You can update attribute with PUT as well.

UPDATE of single attribute == GET -> Modify single attribute in the code -> PUT record data to DB

References:

Upvotes: 2

Related Questions