I have run into an issue trying to retrieve an item from my DynamoDB table. I am trying to retrieve one item by its id, but I get the error: ValidationException: The provided key element does not match the schema
.
I've logged event.pathParameters.id
and this is return the id I would expect, but am struggling to work out the correct syntax.
contactId
is the primary partition key on my table.
I have a primary sort key of userId
- is this the problem? Do I have to use the sort key as well in order to retrieve a record.
dynamo-lib.js
import AWS from 'aws-sdk';
export function call(action, params) {
const dynamoDb = new AWS.DynamoDB.DocumentClient();
return dynamoDb[action](params).promise();
}
get.js
import * as dynamoDbLib from '../libs/dynamodb-lib';
import { success, failure } from '../libs/response-lib';
export async function getReferralDetails(event, context) {
const params = {
TableName: 'contacts',
KeyConditionExpression: 'contactId = :contactId',
ExpressionAttributeValues: {
':contactId': event.pathParameters.id
}
};
try {
const result = await dynamoDbLib.call('query', params);
if (result.Item) {
// Return the retrieved item
return success(result.Item);
} else {
console.log(result);
return failure({ status: false, error: 'Item not found.' });
}
} catch (e) {
console.log(e);
return failure({ status: false });
}
}
Table schema
{
"Table": {
"TableArn": "arn:***",
"AttributeDefinitions": [
{
"AttributeName": "contactId",
"AttributeType": "S"
},
{
"AttributeName": "userId",
"AttributeType": "S"
}
],
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"WriteCapacityUnits": 0,
"ReadCapacityUnits": 0
},
"TableSizeBytes": 0,
"TableName": "contacts",
"TableStatus": "ACTIVE",
"TableId": "b54a6d62-70f6-4c6a-9d91-60abef38615f",
"KeySchema": [
{
"KeyType": "HASH",
"AttributeName": "contactId"
},
{
"KeyType": "RANGE",
"AttributeName": "userId"
}
],
"ItemCount": 0,
"CreationDateTime": 1563814200.835
}
}
Oddly - if I run the below in the terminal. It gives me the record back.
aws dynamodb query \
--table-name contacts \
--key-condition-expression "contactId = :contactId" \
--expression-attribute-values '{
":contactId": { "S": "9902ae80-aca2-11e9-8de1-9329be074f3b" }
}' \
Any help would be appreciated!
Thanks,
Tim
Super late to the game, but maybe someone will stumble upon this question in the future.
In order to query dynamoDB, you have to use the correct format, the one that you're using when running the query from the terminal - notice the JSON structure {"S": "your-id"}.
Keeping this in mind, your query should look like this:
const { marshall } = require('@aws-sdk/util-dynamodb');
... code ...
const params = {
TableName: 'contacts',
KeyConditionExpression: 'contactId = :contactId',
ExpressionAttributeValues: {
':contactId': marshall(event.pathParameters.id)
}
};
Marshalling your object will create the needed format for DynamoDB.
If you still have issues, print out the marshalled version of the ID and make sure it is defined as "S", meaning that it is a string. If it is a number you might get issues. A simple toString() would suffice to resolve that tho'.
Cheers