Reputation: 726
I want to update or create DynamoDB item to get next element:
{
"id": 156,
"date": 12323233.000,
"countries": {
"ua": 1,
"ru": 2}
}
I use python and boto3. So I can check if field countries
exist and if not add it. But that will mean 2 DB requests.
table.update_item(
Key={
'id': 156,
'date': date,
},
UpdateExpression='SET countries = if_not_exists(countries, :countries)',
ExpressionAttributeValues={
':countries': {},
},
)
table.update_item(
Key={
'id': 156,
'date': date,
},
UpdateExpression='ADD countries.#country :inc',
ExpressionAttributeNames={"#country": country},
ExpressionAttributeValues={
':inc': 1
},
)
Is there any way to merge this 2 requests in one?
Upvotes: 6
Views: 1262
Reputation: 145
I had to do something like this recently, and took a while to figure out. I've got a count I want to increment if a page doesn't already exist in my set of "done" pages. If not, it increments and adds the page number to the set. Took a while to realize you can 'append' to a list, but have to 'add' to a set.
try:
res = dbt.update_item(
Key={'pk': 'doc3', 'sk': 'na'},
ReturnConsumedCapacity='INDEXES', ReturnValues='ALL_NEW',
ExpressionAttributeNames={
'#count': 'count',
'#done': 'done',
},
ExpressionAttributeValues={
':1': 1,
':page': page,
':pagelist': set([page]),
},
ConditionExpression="(NOT contains(done, :page))",
UpdateExpression="ADD #done :pagelist, #count :1",
)
print(f'rand int page={page} count={res["Attributes"]["count"]}'
f' CU={res["ConsumedCapacity"]["Table"]}')
except ClientError as err:
if err.response['Error']['Code'] == 'ConditionalCheckFailedException':
print('Already got page=%s (%s)' % (page, err))
else:
raise
Upvotes: 1