Aldee
Aldee

Reputation: 4528

DynamoDB BatchGet always gives "The provided key element does not match the schema"

So I was stuck for a while now with dynamo db's batchGet operation.

Here is my table definition (in serverless)

Resources:
  MyTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    Properties:
      TableName: MyTable
      TimeToLiveSpecification:
        AttributeName: ttl
        Enabled: true
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: myId
          AttributeType: S
        - AttributeName: otherId
          AttributeType: S
      KeySchema:
        - AttributeName: myId
          KeyType: HASH
      GlobalSecondaryIndexes:
        - IndexName: otherIdIndex
          KeySchema:
              - AttributeName: myId
                KeyType: HASH
              - AttributeName: otherId
                KeyType: RANGE
          Projection:
              ProjectionType: ALL

here is how I do batchGet in my function.

await getClient().batchGet({
    RequestItems: {
      'MyTable': {
        Keys: [
          {'myId': { 'S': 'z12345' }},
          {'myId': { 'S': 'z12346' }},
        ],
        ProjectionExpression: 'myId, otherId',
      },
    },
  }).promise();

however, for some reason, I only get an exception The provided key element does not match the schema Did I missed something?

Thanks in advance!


Edit

Searching deeper, I stumbled upon this answer from other post (https://stackoverflow.com/a/32238597/969645). I just realized that I was using the higher-level of the SDK so I have to change my code like this (without defining the type):

await getClient().batchGet({
    RequestItems: {
      'MyTable': {
        Keys: [
          {'myId': 'z12345'},
          {'myId': 'z12346'},
        ],
        ProjectionExpression: 'myId, otherId',
      },
    },
  }).promise();

Now the The provided key element does not match the schema error is gone but I still end up with Internal server error which unfortunately doesn't provide any clue in the logs. Any ideas?

Upvotes: 3

Views: 476

Answers (1)

Florin Mateescu
Florin Mateescu

Reputation: 197

BatchGet - gets the items using the primary key. In your case the PrimaryKey is NOT the partition key but both partition and sort key.

Pk = partition key AND sort key

Your code should be

await getClient().batchGet({
    RequestItems: {
      'MyTable': {
        Keys: [
          {'myId': 'z12345', 'otherId': 'whatever value'},
          {'myId': 'z12346', 'otherId': 'whatever value'},
        ],
        ProjectionExpression: 'myId, otherId',
      },
    },
  }).promise();

Important to understand is that the UNIQUE IDENTIFIER (aka SQL id) is defined in dynamo by using both partition + sort key

Upvotes: 1

Related Questions