DynamoDB PartiQL的SELECT查询返回ValidationException:Unexpected from source。

15

我正在使用Amplify使用DynamoDB进行设置,并使用DynamoDB的Amplify蓝图来设置相应的Lambda。

通过KeyConditionExpression等“传统”方式访问DynamoDB可以正常工作,但今天我想尝试使用executeStatement和PartiQL,但我无法使其工作。

我已经将“dynamodb: PartiQLSelect”权限添加到云前端模板中,其中包含所有其他DynamoDB权限,因此它看起来像:

 "Action": [
                "dynamodb:DescribeTable",
                "dynamodb:GetItem",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:PutItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem",
                "dynamodb:PartiQLSelect"
              ],

我并没有收到任何权限错误,所以我希望那部分没问题,但是即使没有添加那一行,它仍然返回相同的错误。

总是返回的错误是:ValidationException: Unexpected from source"

无论我尝试了什么,都没有帮助。 到目前为止,我的代码相当基本:

const dynamodb2 = new AWS.DynamoDB();

let tableName = "habits_sensors";
if(process.env.ENV && process.env.ENV !== "NONE") {
  tableName = tableName + '-' + process.env.ENV;
}

app.get(path, function(req, res) {
  let params = {
    Statement: `select * from ${tableName}`
  };

  dynamodb2.executeStatement(params, (err, data) => {
    if (err) {
      res.statusCode = 500;
      res.json({error: `Could not get users from : ${tableName} =>` + err});
    } else {
      res.json(data.Items);
    }
  });
});

从 Lambda 返回的完整错误字符串为:

{
    "error": "Could not get users from : habits_sensors-playground =>ValidationException: Unexpected from source"
}

我在我的AWS账户中有一个名为habits_sensors-playground的表格,并且我可以通过传统的方式轻松访问它。这就是为什么“从源头意外”令人困惑的原因。 我理解它是指选择查询中的tableName(在from中)不正确,但名称与我在AWS中拥有的匹配,并且在使用documentclient时可以正常工作。

非常感谢任何可能出错的建议。

4个回答

54

为了回答可能会来到这里的其他人,我自己回答一下。

我从AWS得到了回复,如果表名包含短横线,在使用PartiQL时需要用双引号引用表名(我曾尝试过单引号但没有成功)。

也许在未来的PartiQL版本中这种情况会有所改变。


1
即使在无SQL工作台中 - NanoNova
AWS建议在所有表资源名称(列、表)上使用完整引号。我手头没有链接,但我确实在某个地方读到过这个建议。 - jcollum
谢谢你,伙计。你的回复让我免去了巨大的失望。 - Shaggie
感谢您的报告。这真是出乎意料! - Karl Pokus

8

当表名包含破折号且未加引号时,会出现异常ValidationException:Unexpected from source(CLI:An error occurred (ValidationException) when calling the ExecuteStatement operation: Unexpected from source)。

因此,请更改表名:

aws dynamodb execute-statement --statement \
  "SELECT * FROM my-table WHERE field='string'"

To:

aws dynamodb execute-statement --statement \
  "SELECT * FROM \"my-table\" WHERE field='string'"

或者在您使用的 SDK 中,为了使用 PartiQL,请在表名周围添加双引号"

请注意,WHERE string='value' 使用单引号 ',而表名需要双引号"


2

对于像我一样来到这里的其他人,我有一个生成aws dynamodb execute-statement语句(aws --version 2.x)的powershell脚本,并且遇到了相同的错误。经过很长时间的尝试后,我尝试使用交互式cli并发现我的查询起作用了,所以我最终需要做的是为powershell和AWS CLI都转义双引号,并使用\字符。

$statement = "SELECT id FROM \`"${tablename}\`" WHERE source = '990doc'" 

这种双重转义最终使我达到了需要的效果,并希望能为他人节省大量的沮丧。

1

针对使用AWS SDK(Javascript)出现此错误的任何人,我提供以下解决方案。


const { Items = [] } = await dynamodbClient.executeStatement({
        Statement: `SELECT * FROM "${tablename}" WHERE "_usedId" IS MISSING` 
    }).promise();

如上面的答案所提到的,将表名用双引号括起来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接