Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to append a value to list attribute on AWS DynamoDB?

I'm using DynamoDB as an K-V db (cause there's not much data, I think that's fine) , and part of 'V' is list type (about 10 elements). There's some session to append a new value to it, and I cannot find a way to do this in 1 request. What I did is like this:

item = self.list_table.get_item(**{'k': 'some_key'}) item['v'].append('some_value') item.partial_save() 

I request the server first and save it after modified the value. That's not atomic and looks ugly. Is there any way to do this in one request?

like image 703
Kane Blueriver Avatar asked Jul 08 '15 09:07

Kane Blueriver


People also ask

How do I add a field in DynamoDB?

We can store the values in DynamoDb in 2 ways, (i) In an RDBMS Type of Structure for the DynamoDB, we can add a new Coulmn by executing the same command keeping the "new Column" entry within which the Records in the Existing Table has been created.

How do I update a DynamoDB item?

To update an existing item in an Amazon DynamoDB table, you use the UpdateItem operation. You must provide the key of the item that you want to update. You must also provide an update expression, indicating the attributes that you want to modify and the values that you want to assign to them.

What is attribute value DynamoDB?

Each attribute value is described as a name-value pair. The name is the data type, and the value is the data itself. For more information, see Data Types in the Amazon DynamoDB Developer Guide.

How many attributes can a DynamoDB item have?

There is no limit to the number of attributes but the total item size is limited to 400kb. The maximum item size in DynamoDB is 400 KB, which includes both attribute name binary length (UTF-8 length) and attribute value lengths (again binary length). The attribute name counts towards the size limit.


2 Answers

The following code should work with boto3:

table = get_dynamodb_resource().Table("table_name") result = table.update_item(     Key={         'hash_key': hash_key,         'range_key': range_key     },     UpdateExpression="SET some_attr = list_append(some_attr, :i)",     ExpressionAttributeValues={         ':i': [some_value],     },     ReturnValues="UPDATED_NEW" ) if result['ResponseMetadata']['HTTPStatusCode'] == 200 and 'Attributes' in result:     return result['Attributes']['some_attr'] 

The get_dynamodb_resource method here is just:

def get_dynamodb_resource():     return boto3.resource(             'dynamodb',             region_name=os.environ['AWS_DYNAMO_REGION'],             endpoint_url=os.environ['AWS_DYNAMO_ENDPOINT'],             aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],             aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID']) 
like image 172
LaserJesus Avatar answered Sep 22 '22 19:09

LaserJesus


You can do this in 1 request by using the UpdateItem API in conjunction with an UpdateExpression. Since you want to append to a list, you would use the SET action with the list_append function:

SET supports the following functions:

...

  • list_append (operand, operand) - evaluates to a list with a new element added to it. You can append the new element to the start or the end of the list by reversing the order of the operands.

You can see a couple examples of this on the Modifying Items and Attributes with Update Expressions documentation:

  • The following example adds a new element to the FiveStar review list. The expression attribute name #pr is ProductReviews; the attribute value :r is a one-element list. If the list previously had two elements, [0] and [1], then the new element will be [2].

    SET #pr.FiveStar = list_append(#pr.FiveStar, :r) 
  • The following example adds another element to the FiveStar review list, but this time the element will be appended to the start of the list at [0]. All of the other elements in the list will be shifted by one.

    SET #pr.FiveStar = list_append(:r, #pr.FiveStar) 

The #pr and :r are using placeholders for the attribute names and values. You can see more information on those on the Using Placeholders for Attribute Names and Values documentation.

like image 21
mkobit Avatar answered Sep 18 '22 19:09

mkobit