JavaScriptに慣れていない私が、AWS Lambdaでイベントから年(year)を受け取り、Dynamo DBに問い合わせるコードを書いていたところ、Lambda側のテストでValidationExceptionが発生しました。
const AWS = require("aws-sdk");
AWS.config.update({region: "ap-northeast-1"});
let docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = function(event, context){
// イベントから渡された年を変数に設定(設定されていない場合は2020年に設定)
let input_year = 0;
if (event.year == ""){
input_year = 2020;
}else{
input_year = event.year;
}
// DynamoDBクエリ用のパラメータを設定
let params = {
TableName: 'xxxxxxxxxxx',
KeyConditionExpression: '#yr = :hkey',
ExpressionAttributeNames:{ "#yr": "year" },
ExpressionAttributeValues: { ':hkey': input_year }
};
// クエリを実施(ここでエラー)
docClient.query(params, function(err, data) {
if (err) {
console.log(err);
} else {
console.log("Query succeeded.");
}
context.done(null, resultMap);
});
}
};
↓実行結果
ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type
怪しそうなところ
let input_year = 0;
if (event.year == ""){
input_year = 2020; // 数値
}else{
input_year = event.year; // 文字列
}
数字と文字列が混在してるのはやばいんじゃない?(コーディングしたのは自分)
検証
上記の部分を、以下に置き換えて実行しました。
let input_year = 2020; // 数値にしたところ成功
let input_year = '2020'; // 文字列にしたところエラー
今回はDBのyearを数値で設定していたため、変数の型とDBの型を統一し、数値にしてあげる必要がありそうです。
修正後
let input_year = 0;
if (event.year == ""){
input_year = 2020;
}else{
input_year = parseInt(event.year, 10); // 数値に変換したところエラーがなくなった
}
余談
なぜか、修正前のコードでも、APIGatewayから叩くとエラーにならなかったんですよね、謎。