0

我有一个名为 AWS DynamoDb 的表AccountXX,它将具有 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
}

表上有一个名为的全局二级索引Account_email_hash_salt_gsiAccountXX它具有分区键 email 并具有附加属性hash, saltid.

当我发出以下 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对象,以便我能够成功查询表?

4

1 回答 1

0

发现并解决了问题。问题不在于 DynamoDB 查询或参数构造。根本原因是 Lambda 传递 POST 请求正文和处理程序错误地处理它的问题。处理程序缺少 a JSON.parse(event.body),因此loginToken是一个字符串。因此loginToken.email评估为空导致查询失败。

顺便说一句,我发现在另一个类似问题的答案中提到的Amazon NoSQL Workbench 工具对于探索查询和使用 UI 自动生成它们非常有帮助。我用它来确保查询参数在语法上是正确的,然后在一些故障排除后能够找到根本原因。

于 2021-02-04T11:05:55.967 回答