Search code examples
pythonamazon-dynamodbaws-lambdakeyword-argument

Amazon lambda dynamodb update_item() only accepts keyword arguments


I am trying to save data in dynamodb using update_item for the first time. In another area of my project I have used put_item() successfully. For this new area of code I am saving only items that change, leaving items in the db that are unchanged. Thus, I need to use update_item(). However, I can't seem to figure out why my syntax is not correct for the API call. I am using this directly from the Amazon UI.

Here is my python code:

from __future__ import print_function
import json
import boto3

print('Loading function')

def saveScreenData(event, context):

    dynamodb = boto3.client('dynamodb', region_name='us-east-1', endpoint_url="https://dynamodb.us-east-1.amazonaws.com")

    print('The event: {}'.format(event))

    key = {}
    key['UID'] = event['uid']
    key['screenId'] = event['screenid']
    print('Key: {}'.format(key))

    for item, val in event.items():

        if item != 'uid' and item != 'screenid':
            print("Saving!")
            response = dynamodb.update_item({ 
                "TableName" : "ScreenData",
                "Key" : key,
                "UpdateExpression" : "SET #attrName = :attrValue",
                "ExpressionAttributeNames" : {
                    "#attrName" : item
                },
                "ExpressionAttributeValues" : {
                    ":attrValue" : val
                }
            })

            print('Response: {}'.format(response))


    return response

Here is the output:

START RequestId: 2da9412a-b03d-11e7-9dc8-8fcb305833f6 Version: $LATEST
The event: {'article': '<p>↵    First!↵</p>', 'screenid': '13', 'uid': '0', 'section1': '<h1>↵    Second↵</h1>'}
Key: {'UID': '0', 'screenId': '13'}
Saving!
update_item() only accepts keyword arguments.: TypeError
Traceback (most recent call last):
  File "/var/task/saveScreenData.py", line 30, in saveScreenData
    ":attrValue" : val
  File "/var/runtime/botocore/client.py", line 310, in _api_call
    "%s() only accepts keyword arguments." % py_operation_name)
TypeError: update_item() only accepts keyword arguments.

END RequestId: 2da9412a-b03d-11e7-9dc8-8fcb305833f6

I have researched the update_item docs (https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) and have modeled my query after this SO q&a by mkobit (https://stackoverflow.com/users/627727/mkobit): https://stackoverflow.com/a/30604746/8027640

I have played with variations on the syntax, including adding the dictionary {"S" : "maybe this works"} instead of my variable val, and have also tried changing the variable to some static content to see if it works, but no luck.

Clearly this is a syntax issue, but I have been unable to track it down. Suggestions?


Solution

  • I think the example your are using is based on boto2 which has quite different interface comparing to boto3.

    Instead, look into the boto3 documentation, you should use keyword arguments as the error states (and you are using the dictionary). Your request should look approximately like this:

    response = dynamodb.update_item(
        TableName="ScreenData",
        Key=key,
        UpdateExpression="SET #attrName = :attrValue",
        ExpressionAttributeNames={
            "#attrName" : item
        },
        ExpressionAttributeValues={
            ":attrValue" : val
        }
    )