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?
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.
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.
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.
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.
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'])
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With