2016-02-02 5 views
4

У меня есть функция, которая производит пары (some_key, some_value), которые я хочу поставить в свой DynamoDB. Если элемент с ключом some_key уже присутствует, я хочу добавить some_value в атрибуты value. В противном случае я хочу создать такой элемент. Следуя примеру в the docs, кажется, что функция if_not_exists должна делать то, что я хочу. У меня возникают проблемы с синтаксисом, потому что мой код возвращает ошибку:DynamoDB обновить счетчик (или вставить ключ)

>>>> table.update_item(
     Key={ 
      'key': my_key 
     }, 
     UpdateExpression="set my_value = if_not_exist(my_value + :inc, :inc)", 

     ExpressionAttributeValues={ 
      ':inc': my_increment, 
     }, 
     ReturnValues="UPDATED_NEW" 
    ) 

ClientError: An error occurred (ValidationException) when calling the UpdateItem operation: 
Invalid UpdateExpression: Syntax error; token: "+", near: "coocc + :val" 

ответ

3

Вы можете сделать это следующим образом:

table.update_item(
    Key={ 
     'key': my_key 
    }, 
    UpdateExpression="SET my_value = if_not_exists(my_value, :start) + :inc", 

    ExpressionAttributeValues={ 
     ':inc': my_increment, 
     ':start': 0, 
    }, 
    ReturnValues="UPDATED_NEW" 
) 

update_item создаст ли новый элемент или обновить существующий.

UpdateExpression будет проверять, существует ли уже my_value и использовать существующие my_value + :inc.

Если my_value не существует, то он будет использовать :start в качестве начального значения.

9

Для этого типа операций, которые вы могли бы просто использовать ADD функции. Из docs:

ADD - Adds the specified value to the item, if the attribute does not already exist. If the attribute does exist, then the behavior of ADD depends on the data type of the attribute

Итак, используя boto3.client() вы можете сделать следующее:

client.update_item(
    TableName='MyTable', 
    Key={'myhash': {'S': 'myvalue'}}, 
    UpdateExpression="ADD #counter :increment", 
    ExpressionAttributeNames={'#counter': 'counter'}, 
    ExpressionAttributeValues={':increment': {'N': '1'}} 
) 

Это создаст counter поле, если он не существует, и это увеличит его, если он существует.

+2

Это, безусловно, лучший ответ! – alexcasalboni

Смежные вопросы