我有一个名为AccountXX
的AWS DynamoDb表,它将具有JSON结构的项目存储为:
{
"id": "some id value", // also the partition key for the table
"name": "a name",
"email": "an email address",
"salt": [12, 3, ... ], // an array of random values
"hash": [1, 5, ... ], // an array representing a hashed password
... // and some more attributes
}
在AccountXX
表上有一个名为Account_email_hash_salt_gsi
的全局二级索引,该索引具有分区键email,并具有hash, salt
和id
的附加属性。
当我发出以下AWS CLI命令时,我能够成功地查询表中的一个项目:
aws dynamodb query --table AccountXX
--index-name Account_email_hash_salt_gsi
--key-condition-expression "email = :emailValue"
--expression-attribute-values file://values.json
values.json
的内容为:
{":emailValue":{"S": "someone@somewhere.in"}}
然而,当我使用AWS.DynamoDB.DocumentClient
实例使用以下参数对象发出类似的调用时,我得到一个错误:
const params = {
TableName: accountTable, // will be set to 'AccountXX'
IndexName: "Account_email_hash_salt_gsi",
KeyConditionExpression:"#email = :emailValue",
ExpressionAttributeNames: {
"#email": "email"
},
ExpressionAttributeValues: {
":emailValue": {"S": loginToken.email}
},
ScanIndexForward: false
};
我得到的错误是:
ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
我还尝试使用修改后的参数对象,如下所示:
const params = {
TableName: accountTable, // will be set to 'AccountXX'
IndexName: "Account_email_hash_salt_gsi",
KeyConditionExpression:"#email = :emailValue",
ExpressionAttributeNames: {
"#email": "email"
},
ExpressionAttributeValues: {
":emailValue": loginToken.email // directly using string type
},
ScanIndexForward: false
};
在这种情况下,我得到以下错误:
ValidationException: ExpressionAttributeValues must not be empty
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
在这两种情况下,我的DynamoDB DocumentClient查询发出为:
const data = await dynamo.query(params).promise();
我应该做些什么来修复params
对象,以便我能够成功地查询表?
找到并修复了问题。问题不在于DynamoDB查询或参数构造。根本原因是Lambda传递POST请求体的问题,处理程序错误地处理它。处理程序缺少JSON.parse(event.body)
,因此loginToken
是一个字符串。因此,loginToken.email
被求值为空,导致查询失败。
顺便说一句,我发现在另一个类似问题的回答中提到的Amazon NoSQL Workbench工具在探索查询和使用UI自动生成查询方面非常有帮助。我使用它来确保查询参数在语法上是正确的,然后在进行一些故障排除后能够找到根本原因。