Newbie here. I'm trying to query a DynamoDB table from a Lambda function using partition and sort key.
My table has 5 columns, with the partition key id (string) and sort key owner (string).
Below is my lambda function. It is returning null.
const AWS = require('aws-sdk');
AWS.config.update({region: process.env.REGION});
const ddb = new AWS.DynamoDB();
exports.handler = async (event, context) => {
const id = event.id;
const owner = event.owner;
const params = {
TableName: process.env.TABLE_NAME,
KeyConditionExpression: "id = :id and owner = :owner",
ExpressionAttributeValues: {
":id": { S: id },
":owner": { S: owner },
}
};
await ddb.query(params, function(err, data) {
if (err) {
return err;
} else {
return data;
}
});
My test event for the lambda function looks like:
{
"id": "someID",
"owner": "someOwner"
}
I do have an item in the DDB table with the partition key id = "someID" and sort key owner = "someOwner".
Why is this function returning null?
CodePudding user response:
one immediate issue I see with the query is "owner" is a reserved DynamoDB keyword. See a list of them here. You'll want to use the ExpressionAttributeNames parameter to substitute "owner" with "#owner".
I'd also suggest using the promise syntax instead of callback functions. When you return from inside function (err, data)...
, you're actually returning from the callback function instead of the lambda function (as jarmod, hinted, beat me to it!). Here's how I'd rewrite the query:
try {
const data = await ddb.query(params).promise();
// then, you can get the result of the query in data.Items
console.log(data.Items);
return data.Items;
} catch (err) {
console.log(err);
// return an empty array, or whatever you wish in the case of an error
return [];
}
One final suggestion is to use the DynamoDB.DocumentClient instead of plain old DynamoDB. That way you don't need to specify the type of your ExpressionAttributeValues
. So, params
becomes:
const params = {
TableName: process.env.TABLE_NAME,
KeyConditionExpression: "id = :id and #owner = :owner",
ExpressionAttributeValues: {
":id": id,
":owner": id,
},
ExpressionAttributeNames: {
"#owner": "owner"
}
};
Much cleaner!