【问题标题】:DynamoDB asks for Partition Key of main table when querying GSIDynamoDB查询GSI时询问主表的Partition Key
【发布时间】:2022-11-17 00:46:04
【问题描述】:

所以,问题是,我正在尝试查询 DynamoDB 上的 GSI 表并得到一个非常奇怪的行为。 主表架构如下

- Partition key:    test_id (string)
- Sort key:         version (string)
- Other attributes  (createdAt, tags, etc)

我想获取每个具有等于 v0_test 的 sort_key 的条目,而不按分区键过滤。为了做到这一点并避免全面扫描,我创建了一个 GSI(全球二级索引),如下所示:

- Partition key:    version (string)
- Sort key:         createdAt (number)
- Other attributes  (test_id, tags, etc)

当从 AWS 控制台查询时,我可以查询每个等于 v0_test 的分区键,我得到了预期的结果,但是当我从 lambda 函数 (runtime: nodejs16.x) 内部查询时,我得到了一个错误。 查询代码如下:

const dynamoDb = new AWS.DynamoDB.DocumentClient();
let params = {
    TableName: dynamoTable,
    IndexName: dynamoTableIndex ,
    KeyConditionExpression: 'version = :v0 AND createdAt BETWEEN :tLower AND :tUpper',
    ExpressionAttributeValues: {
        ':v0': 'v0_test',
        ':tUpper': Math.floor(Date.now() / 1000).toString(),
        ':tLower': '0'
    }
};
let result = await dynamoDb.query(params).promise();
console.log("Success", result);

我得到的错误是

ERROR ValidationException: Query condition missed key schema element: test_id

如您所见,它正在请求主表的分区键。

我尝试过的事情:

  • 使用 AWS.DynamoDB 而不是 AWS.DynamoDB.DocumentClient。同样的错误
  • 在查询中将 version 更改为 test_id。得到ERROR ValidationException: Query condition missed key schema element: version
  • KeyConditionExpression 上同时发送versiontest_id。出现以下错误:ERROR ValidationException: KeyConditionExpressions must only contain one condition per key
  • 新的 Dynamodb 表,新的 GSI。同样的错误

我根本没想到。这是我第一次使用 DynamoDB,但据我了解,GSI(或其中之一)背后的想法是能够通过主分区键以外的其他属性查询 DynamoDB 表,而无需进行全面扫描。

任何帮助表示赞赏,如果您需要更多详细信息,请询问!这也是我第一次在 StackOverflow 上提问,所以我确定我会错过一些东西。

编辑

测试了建议的解决方案并收到一个错误提示模式错误,这是一个新错误并让我开始思考,所以我尝试指定 ExpressionAttributeNames 并且成功了!。 我使用 DocumentClient 创建了如下请求:

const dynamoDb = new AWS.DynamoDB.DocumentClient();
let params = {
    TableName: 'CLASSIFIER_TESTS_DEV_us-east-1',
    IndexName: 'version-createdAt-index',
    KeyConditionExpression: '#versionAttr = :version AND #ca BETWEEN :tLower AND :tUpper',
    ExpressionAttributeNames: {
        "#versionAttr": "version",
        "#ca": "createdAt"
    },
    ExpressionAttributeValues: {
        ":version": "v0_test",
        ":tUpper": Date.now(),
        ":tLower": 0
    }
};
let result = await dynamoDb.query(params).promise();

感谢大家! 我仍然认为它应该像我第一次做的那样工作,因为这是每个人在教程/示例/文档中做的方式,但是哦,好吧,让它工作,这就是现在最重要的。

【问题讨论】:

  • 真的好像你把一些名字弄混了。也许从控制台显示表和索引定义的屏幕截图?
  • 您确定变量dynamoTableIndex 包含 GSI 的名称吗?
  • @Charles 名字没问题。根据公司政策,我不能分享截图。我现在正在测试一些看起来很有希望的东西。如果我不能让它工作,我会用虚拟数据创建一个虚拟表并更新我的帖子
  • @MarkB 变量确实包含 GSI 的正确名称,但现在我正在使用硬编码的名称进行测试,以消除这种意义上的每个可能的错误。谢谢

标签: aws-lambda amazon-dynamodb serverless dynamodb-queries amazon-dynamodb-index


【解决方案1】:

这应该不是问题。我建议如下:

  1. 在本地测试,让您的 DynamoDB API 调用从您的本地计算机运行,这将确保 Lambda 调用不会导致任何问题
  2. 将您的 TableName 和 IndexName 硬编码为参数中的字符串。
  3. 如果上述仍然导致问题,请尝试相同的逻辑,但这次是来自基表的查询。

    如果您在那之后仍然遇到问题,请告诉我,很乐意提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多