Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB validation exception on lambda

I am getting the following error when calling my lambda skill

ClientError: An error occurred (ValidationException) 
when calling the CreateTable operation: 1 validation error detected: 
Value '[com.amazonaws.dynamodb.v20120810.KeySchemaElement@2273ace6, 
com.amazonaws.dynamodb.v20120810.KeySchemaElement@4d13ab9, 
com.amazonaws.dynamodb.v20120810.KeySchemaElement@115e22b2]' at 
'keySchema' failed to satisfy constraint: Member must have length less than or equal to 2

Here is the code:

def write_values_to_db(ddid, token, intent):
    pid = ...
    dynamodb_client = boto3.client('dynamodb')
    try:
        response = dynamodb_client.create_table(
            AttributeDefinitions=[
                {
                    'AttributeName': 'pid',
                    'AttributeType': 'S',
                },
                {
                    'AttributeName': 'ddid',
                    'AttributeType': 'S',
                },
                {
                    'AttributeName': 'token',
                    'AttributeType': 'S',
                },
            ],
            KeySchema=[
                {
                    'AttributeName': 'pid',
                    'KeyType': 'HASH',
                },
                {
                    'AttributeName': 'ddid',
                    'KeyType': 'RANGE',
                },
                {
                    'AttributeName': 'token',
                    'KeyType': 'RANGE',
                },
            ],
            ProvisionedThroughput={
                'ReadCapacityUnits': 5,
                'WriteCapacityUnits': 5,
            },
            TableName='Values',
        )
    except dynamodb_client.exceptions.ResourceInUseException:
        dynamodb_client.put_item(
            TableName='Values',
            Item={
                'pid': pid,
                'ddid': ddid,
                'token': token
            }
        )

According to my dashboard the error is on the TableName='Values' line. I was following a tutorial and only changed certain things so I don't see why this is not working. I can't test on a local environment because I have region/credential issues.

like image 334
Jeremy Fisher Avatar asked Sep 08 '17 22:09

Jeremy Fisher


People also ask

Can Lambda Access DynamoDB?

AWS Lambda: Allows a Lambda function to access an Amazon DynamoDB table. This example shows how you might create an identity-based policy that allows read and write access to a specific Amazon DynamoDB table. The policy also allows writing log files to CloudWatch Logs.

What causes DynamoDB system errors?

The most likely cause is an invalid AWS access key ID or secret key. This error can occur for several reasons, such as a required parameter that is missing, a value that is out of range, or mismatched data types. The error message contains details about the specific part of the request that caused the error.

When creating a trigger from a DynamoDB table to a Lambda function which DynamoDB permission?

For more information about using Lambda with DynamoDB Streams, see DynamoDB Streams and AWS Lambda triggers. To grant permissions to Lambda, use the permissions policy that is associated with the Lambda function's IAM role (also known as an execution role). Specify this policy when you create the Lambda function.


2 Answers

The KeySchema in your code should be as below,

AttributeDefinitions=[
            {
                'AttributeName': 'pid',
                'AttributeType': 'S',
            }
        ],
KeySchema=[
                {
                    'AttributeName': 'pid',
                    'KeyType': 'HASH'
                }
]

You can have only one Hash Key and One Range Key Max.

If you want to additional indexes, you can create them with secondary indexes.

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html

Below would be the syntax for Global Secondary Index.

Reference: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html

GlobalSecondaryIndexes: [
    {
      IndexName: 'STRING_VALUE', /* required */
      KeySchema: [ /* required */
        {
          AttributeName: 'STRING_VALUE', /* required */
          KeyType: HASH | RANGE /* required */
        },
        /* more items */
      ],
      Projection: { /* required */
        NonKeyAttributes: [
          'STRING_VALUE',
          /* more items */
        ],
        ProjectionType: ALL | KEYS_ONLY | INCLUDE
      },
      ProvisionedThroughput: { /* required */
        ReadCapacityUnits: 0, /* required */
        WriteCapacityUnits: 0 /* required */
      }
    },
    /* more items */
  ]
like image 167
Kannaiyan Avatar answered Sep 23 '22 22:09

Kannaiyan


AWS explicate that in the documentation:

For a composite primary key (partition key and sort key), you must provide exactly two elements, in this order: The first element must have a KeyType of HASH, and the second element must have a KeyType of RANGE.

They only allow two KeySchema: one KeyType as HASH and another KeyType as RANGE.

...
"KeySchema": [
    {
        "AttributeName": "ForumName",
        "KeyType": "HASH"
    },
    {
        "AttributeName": "Subject",
        "KeyType": "RANGE"
    }
]
... 
like image 44
Jose Carlos Ramos Carmenates Avatar answered Sep 25 '22 22:09

Jose Carlos Ramos Carmenates