I have the next error in my DynamoDB request:
{
"__type":"com.amazon.coral.validate#ValidationException",
"message":"Invalid UpdateExpression:
Two document paths overlap with each other; must remove or rewrite one of
these paths; path one: [cart, items, [1], vat-item], path two: [cart, items]"
}
I am using the next expression:
"UpdateExpression":"SET
cart.#listName[0].quantity = cart.#listName[0].quantity + :quantity1,
cart.#listName[0].price = :price1,
cart.#listName[0].#vatItem = :vatItem1,
cart.#listName[1].quantity = cart.#listName[1].quantity + :quantity2,
cart.#listName[1].price = :price2,
cart.#listName[1].#vatItem = :vatItem2,
cart.#listName = list_append (cart.#listName, :jsonObject)"}
Is there any hack to do work fine "set elements and add anothers"?
I found this question on stackoverflow but this guy is trying to do delete and set, and me only set.
Added an MRE in python for those willing to try at home:
import boto3
TABLE_NAME = "pk-only"
TABLE_RESOURCE = boto3.resource("dynamodb").Table(TABLE_NAME)
DDB_CLIENT = boto3.client("dynamodb")
def create_table():
DDB_CLIENT.create_table(
AttributeDefinitions=[{"AttributeName": "PK", "AttributeType": "S"}],
TableName=TABLE_NAME,
KeySchema=[{"AttributeName": "PK", "KeyType": "HASH"}],
BillingMode="PAY_PER_REQUEST"
)
def add_sample_item():
TABLE_RESOURCE.put_item(
Item={
"PK": "append_and_update",
"list": [
{
"value": "a"
}
]
}
)
def update():
TABLE_RESOURCE.update_item(
Key={
"PK": "append_and_update"
},
UpdateExpression="SET #l = list_append(#l, :newItem), #l[0].#val = :newVal",
ExpressionAttributeNames={
"#l": "list",
"#val": "value",
},
ExpressionAttributeValues={
":newVal": "b",
":newItem": {"M": {"value": {"S": "c"}}}
}
)
def main():
# create_table()
add_sample_item()
update()
if __name__ == "__main__":
main()
Interesting question.
What you wanted to do is:
"UpdateExpression":"SET
cart.#listName[0].quantity = cart.#listName[0].quantity + :quantity1,
cart.#listName[0].price = :price1,
cart.#listName[0].#vatItem = :vatItem1,
cart.#listName[1].quantity = cart.#listName[1].quantity + :quantity2,
cart.#listName[1].price = :price2,
cart.#listName[1].#vatItem = :vatItem2,
cart.#listName = list_append (cart.#listName, :jsonObject)"}
As you noticed, this is not allowed - you are not allowed to replace #listName (which is what the last assignment is doing) and change specific subattributes of #listName ([0] and [1]) in the same update.
But luckly, there is a different, rather obscure, way to append to a list, which will work in your case:
If your expression asks to set cart.#listName[1000], where 1000 is known to be beyond the length of the list (it can be much higher than the length of the list, unlike your solution), then this element is appended at the end of the list. It is appended really at the end of the list - if the list only had 5 items, the element is added as the 6th, not as the 1000th. Another important thing to note is that if you set elements 1000, 1001, and 1002 in the list, they are appended by this numeric order.
So knowing these facts, you can change your code to:
"UpdateExpression":"SET
cart.#listName[0].quantity = cart.#listName[0].quantity + :quantity1,
cart.#listName[0].price = :price1,
cart.#listName[0].#vatItem = :vatItem1,
cart.#listName[1].quantity = cart.#listName[1].quantity + :quantity2,
cart.#listName[1].price = :price2,
cart.#listName[1].#vatItem = :vatItem2,
cart.#listName[1000] = :jsonObject0,
cart.#listName[1001] = :jsonObject1,
cart.#listName[1002] = :jsonObject2"}
If you're worried that 1000 might not be high enough, just replace it with 1000000. The actual number doesn't matter - the statement will not add a lot of null elements in the array. The indexes can be as high as you want - they just need to be higher than the possible length of the existing list.
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