I've created a DynamoDB table, and in my Python code, I have the resource initialised as follows:
self.dynamodb = self.session.resource('dynamodb').Table('aws-ci')
The table has just one index/key, with the name environment
. I am trying to PUT
into it, an object as follows:
{
"environment": "beta",
"X": {
"current_sha": "sha1",
"deployed": true,
"prev_sha": "sha2",
"status": "inactive"
},
"Y-Z": {
"current_sha": "sha1",
"deployed": false,
"prev_sha": "sha2",
"status": "active"
}
}
where, X
and Y-Z
are the names of micro-services. My insertion code is as follows:
def put_service_data(self, environment, service_name, service_data, status = None):
get_previous = self.dynamodb.get_item(
Key = {
'environment': environment
}
).get(service_name)
service_data['prev'] = get_previous and get_previous.get('current_sha') or 'NULL'
if status == 'rollback' and get_previous:
service_data['current'] = get_previous.get('current_sha')
service_data['prev'] = get_previous.get('prev_sha')
set_query = "SET {0}.current_sha = :current, {0}.prev_sha = :prev, {0}.deployed = :is_deployed, {0}.current_status = :status".format(service_name)
updated = self.dynamodb.update_item(
Key = {
'environment': environment
},
UpdateExpression = set_query,
ExpressionAttributeValues = {
':current': service_data.get('current'),
':prev': service_data.get('prev'),
':status': service_data.get('status'),
':is_deployed': service_data.get('deployed')
},
ReturnValues = "ALL_NEW"
)
return updated
Previously, instead of {0}.current_status
, I had {0}.status
, but that raised the following error:
An error occurred (
ValidationException
) when calling theUpdateItem
operation: InvalidUpdateExpression
: Attribute name is a reserved keyword; reserved keyword:status
Anyway, I changed that attribute name name to current_status
and tried the insertion again, only this time I am receiving:
An error occurred (
ValidationException
) when calling theUpdateItem
operation: The document path provided in the update expression is invalid for update
when trying to set attributes for service X, and the following when trying for Y-Z:
An error occurred (
ValidationException
) when calling theUpdateItem
operation: InvalidUpdateExpression
: Syntax error; token: "-", near: "Y-Z"
I'm currently unable to understand how the update_item
call should work.
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.
The most likely cause of a failed read or a failed write is throttling. For BatchGetItem , one or more of the tables in the batch request does not have enough provisioned read capacity to support the operation. For BatchWriteItem , one or more of the tables does not have enough provisioned write capacity.
UpdateItem behaves as an “UPSERT” operation. This means that if you try to update an item that doesn't exist, DynamoDB will automatically create it for you. Like with PutItem , you can add conditions to your UpdateItem API calls to modify this behavior, but there is no way to implement it service-side.
The only way to update multiple items at the same time is use TransactionWrite operation provided by DynamoDB. But it comes with a limitation (25 at most for example). So keep in mind with that, you probable should do some limitation in your application as well.
Have you tried this? http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ExpressionPlaceholders.html#ExpressionAttributeNames
set_query = "SET #service_name.current_sha = :current, #service_name.prev_sha = :prev, #service_name.deployed = :is_deployed, #service_name.current_status = :current_status"
updated = self.dynamodb.update_item(
Key = {
'environment': environment
},
UpdateExpression = set_query,
ExpressionAttributeValues = {
':current': service_data.get('current'),
':prev': service_data.get('prev'),
':current_status': service_data.get('status'),
':is_deployed': service_data.get('deployed')
},
ExpressionAttributeNames = {
'#service_name': service_name,
},
ReturnValues = "ALL_NEW"
)
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