【问题标题】:How to specify parameters for DynamoDB PartiQL in Nodejs如何在 Nodejs 中为 DynamoDB PartiQL 指定参数
【发布时间】:2021-05-25 09:32:55
【问题描述】:

我想在 NodeJs 中使用 PartiQL 在 DynamoDb 上执行 SELECT 查询,但出现错误。

一个简单的语句没有问题。

    const r = await client.send(
      new ExecuteStatementCommand({
          Statement: `SELECT * FROM Users WHERE userId in ['abcd1234']`
      })
    )

但是当尝试执行带参数的语句时,我得到了一个错误。

代码

    const r2 = await client.send(
      new ExecuteStatementCommand({
          Statement: `SELECT * FROM Users WHERE userId in ?`,
          Parameters: [
            ['abcd1234']
          ]
      })
    )

错误

{
  "errorType": "ValidationException",
  "errorMessage": "1 validation error detected: Value '[]' at 'parameters' failed to satisfy constraint: Member must have length greater than or equal to 1",
  "trace": [
    "ValidationException: 1 validation error detected: Value '[]' at 'parameters' failed to satisfy constraint: Member must have length greater than or equal to 1",
    "    at deserializeAws_json1_0ExecuteStatementCommandError (/var/task/node_modules/@aws-sdk/client-dynamodb/dist/cjs/protocols/Aws_json1_0.js:2202:41)",
    "    at processTicksAndRejections (internal/process/task_queues.js:97:5)",
    "    at async /var/task/node_modules/@aws-sdk/middleware-serde/dist/cjs/deserializerMiddleware.js:6:20",
    "    at async /var/task/node_modules/@aws-sdk/middleware-signing/dist/cjs/middleware.js:12:24",
    "    at async StandardRetryStrategy.retry (/var/task/node_modules/@aws-sdk/middleware-retry/dist/cjs/defaultStrategy.js:56:46)",
    "    at async /var/task/node_modules/@aws-sdk/middleware-logger/dist/cjs/loggerMiddleware.js:6:22",
    "    at async /var/task/node_modules/@aws-sdk/lib-dynamodb/dist/cjs/commands/ExecuteStatementCommand.js:29:26",
    "    at async Runtime.handler (/var/task/save.js:39:16)"
  ]
}

有人有解决办法吗?

这是完整的代码。


  const client = DynamoDBDocumentClient.from(
    new DynamoDBClient({})
  );

    // this works
    const r = await client.send(
      new ExecuteStatementCommand({
          Statement: `SELECT * FROM Users WHERE userId in ['abcd1234']`
      })
    )

    // this gets an error
    const r2 = await client.send(
      new ExecuteStatementCommand({
          Statement: `SELECT * FROM Users WHERE userId in ?`,
          Parameters: [
            ['abcd1234']
          ]
      })
    )

【问题讨论】:

  • 这个我没办法给你测试,但是你传入的参数不应该用双引号括起来吗?似乎您正在尝试将嵌套数组对象传递给应该是一个数组,该数组只包含一个作为字符串传入的项目。不确定我是否正确,因此我将其发布为评论而不是答案。希望对您有所帮助。

标签: javascript node.js amazon-dynamodb aws-sdk-nodejs partiql


【解决方案1】:

据我所知,不太可能做你想做的事情(将字符串数组作为参数传递给准备好的语句,作为 IN 运算符的右手参数?)。

看来你能做的最好的事情是:

executeStatement({
  Statement: `SELECT * FROM Users WHERE userId in [?, ?]`,
  Parameters: [
    {"S": "firstId"},
    {"S": "secondId"}, 
    // ...etc.
  ]
})

请注意,Parameters 属性采用键值对数组。每个参数属性值都被描述为一个名称-值对。名称是数据类型(例如 "S" 表示字符串),值是数据本身(例如用户 ID。)

在您的情况下,如果您有一个用户列表,您可以执行以下操作:


const users = [
  { id: "id-1" },
  { id: "id-2" },
  { id: "id-3" },
]

executeStatement({
  Statement: `SELECT * FROM Users WHERE userId in [${users.map(() => '?').join(',')}]`,
  Parameters: 
    users.map(user => ({"S": user.id}))  
})

请注意,您可以传递的参数数量可能存在上限,但我在任何地方都找不到这个数字。

【讨论】:

  • 以及如何更新对象路径?
【解决方案2】:
// Before
SELECT * FROM Users WHERE userId in ?

// After
SELECT * FROM Users WHERE userId in '?'

【讨论】:

猜你喜欢
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 2022-11-17
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 2017-08-12
相关资源
最近更新 更多