Reputation: 1874
How can I append an item to an existing map in dynamodb I want to add a new set of location/name/tags.
The structure in dynamodb looks like the below
{
"user": "xyz",
"itemdetails": [
{
"location": "67666",
"name": "item1",
"tags": [
"k7866"
]
},
{
"location": "45444",
"name": "item12",
"tags": [
"ha23",
"ju4532"
]
}
}
I tried the below but get a
"Invalid UpdateExpression: Incorrect operand type for operator or function; operator: ADD, operand type: MAP"
response = table.update_item(
Key={
'user': "xyz",
},
UpdateExpression = 'ADD #itemdetails :newItems',
ExpressionAttributeNames = {
'#itemdetails' : 'ids'
},
ExpressionAttributeValues = {
':newItems' : {"name":name,
"location":location,
"tags":tags
}
},
ReturnValues="UPDATED_NEW"
Upvotes: 2
Views: 2029
Reputation: 1379
I'm the author of Lucid-Dynamodb, a minimalist wrapper to AWS DynamoDB. This problem can be easily solved using this python library.
Reference: https://github.com/dineshsonachalam/Lucid-Dynamodb#8-add-an-attribute-to-the-list
from LucidDynamodb.Operations import DynamoDb
import os
import logging
logging.basicConfig(level=logging.INFO)
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
table_schema = {
"TableName": "test",
"KeySchema": [
{
"AttributeName": "user",
"KeyType": "HASH"
}
],
"AttributeDefinitions": [
{
"AttributeName": "user",
"AttributeType": "S"
}
],
"GlobalSecondaryIndexes": [],
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
}
if __name__ == "__main__":
# 1. create a new table
db = DynamoDb(region_name="us-east-1",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
table_creation_status = db.create_table(
TableName=table_schema.get("TableName"),
KeySchema=table_schema.get("KeySchema"),
AttributeDefinitions=table_schema.get("AttributeDefinitions"),
GlobalSecondaryIndexes=table_schema.get("GlobalSecondaryIndexes"),
ProvisionedThroughput=table_schema.get("ProvisionedThroughput")
)
if(table_creation_status == True):
logging.info("{} table created successfully".format(table_schema.get("TableName")))
else:
logging.error("{} table creation failed".format(table_schema.get("TableName")))
# 2. Create a new item
item_creation_status = db.create_item(
TableName=table_schema.get("TableName"),
Item = {
"user": "xyz",
"itemdetails": [{
"location": "67666",
"name": "item1",
"tags": [
"k7866"
]
},
{
"location": "45444",
"name": "item12",
"tags": [
"ha23",
"ju4532"
]
}
]
}
)
if(item_creation_status == True):
logging.info("Item created successfully")
else:
logging.warning("Item creation failed")
# 3. Add/Append an attribute to the list
item_update_status = db.update_item(
TableName=table_schema.get("TableName"),
Key={
"user": "xyz"
},
AttributesToUpdate={
"itemdetails": {
"location": "333",
"name": "item3",
"tags": [
"tag333"
]
}
},
Operation="ADD_ATTRIBUTE_TO_LIST"
)
if(item_update_status == True):
logging.info("Update is successful")
else:
logging.warning("Update failed")
item = db.read_item(
TableName=table_schema.get("TableName"),
Key={
"user": "xyz"
})
if(item != None):
logging.info("Item: {}".format(item))
else:
logging.warning("Item doesn't exist")
**Output: **
dineshsonachalam@macbook Dynamodb-experiment % python test.py
INFO:root:test table created successfully
INFO:root:Item created successfully
INFO:root:Update is successful
INFO:root:Item:
{
'itemdetails': [{
'name': 'item1',
'location': '67666',
'tags': ['k7866']
}, {
'name': 'item12',
'location': '45444',
'tags': ['ha23', 'ju4532']
}, {
'name': 'item3',
'location': '333',
'tags': ['tag333']
}],
'user': 'xyz'
}
Upvotes: 2
Reputation: 1874
I solved it now with
UpdateExpression = 'SET itemdetails = list_append(itemdetails, :newitem)',
ExpressionAttributeValues={
":newitem": [
{
"name":"TEST",
"location":"TEST",
"tags":tags
}
]
},
ReturnValues="UPDATED_NEW"
)
Upvotes: 3