我有一个PostConfirmation
lambda 触发器,它 通过GraphQL (appsync https 调用)将数据添加到DynamoDB,然后我在lambda 中查询该信息。当我通过我的应用程序 UI 手动测试时,一切正常。但是,当通过 Jest 测试执行时,由于在 DynamoDB 中找不到假定的记录信息,50% 以上的时间会出现错误。当我通过 UI 应用程序手动测试时,不会出现此问题。仅在通过 Jest 测试执行时。PreTokenGeneration
我检查了PostConfirmation
添加 DynamoDB 记录的 Cloudwatch 时间戳,PreTokenGeneration
并检查了 DynamoDB 中的 createDate。时间戳看起来不错。例如:
PostConfirmation
表示已添加记录的日志条目的时间戳为2020-08-24T17:51:06.463Z
。- 添加的记录 (createdAt)的DynamoDB
createdAt
表示该记录是在2020-08-24T17:51:06.377Z
. - lambda "
PostConfirmation
END RequestId: xxxxx" 的时间戳为2020-08-24T17:51:06.465-05:00
- PreTokenGeneration lambda 从查询结果开始,
2020-08-24T17:51:12.866Z
在2020-08-24T17:51:13.680Z
查询结果中表示它没有找到任何记录。
有人可以帮助我或提示我为什么会发生这种情况和/或我该如何解决这个问题?先感谢您。
考虑到@noel-llevares 的答案,我修改了 VTL 模板以包含 ConsistentRead=true 但问题仍然存在。
这是为保存操作记录的 RequestMapping
{
"logType": "RequestMapping",
"path": [
"createAccountMember"
],
"fieldName": "createAccountMember",
"resolverArn": "arn:aws:appsync:xx-xxxx-x:111111111:apis/<redacted>/types/Mutation/resolvers/createAccountMember",
"requestId": "<redacted>",
"context": {
"arguments": {
"input": {
"id": "<redacted>",
"userID": "<redacted>",
"accountID": "<redacted>",
"membershipStatus": "active",
"groupsEnrolledIn": [
<redacted>
],
"recordOwner": "<redacted>",
"createdAt": "2020-08-25T05:11:10.917Z",
"updatedAt": "2020-08-25T05:11:10.917Z",
"__typename": "AccountMember"
}
},
"stash": {},
"outErrors": []
},
"fieldInError": false,
"errors": [],
"parentType": "Mutation",
"graphQLAPIId": "<redacted>",
"transformedTemplate": "\n\n\n\n\n\n\n\n{\n \"version\": \"2018-05-29\",\n \"operation\": \"PutItem\",\n \"key\": {\n \"id\": {\"S\":\"<redacted>\"}\n} ,\n \"attributeValues\": {\"accountID\":{\"S\":\"<redacted>\"},\"createdAt\":{\"S\":\"2020-08-25T05:11:10.917Z\"},\"recordOwner\":{\"S\":\"<redacted>\"},\"__typename\":{\"S\":\"AccountMember\"},\"id\":{\"S\":\"<redacted>\"},\"membershipStatus\":{\"S\":\"active\"},\"userID\":{\"S\":\"<redacted>\"},\"groupsEnrolledIn\":{\"L\":[{\"S\":\"<redacted>\"},{\"S\":\"<redacted>\"},{\"S\":\"<redacted>\"}]},\"updatedAt\":{\"S\":\"2020-08-25T05:11:10.917Z\"}},\n \"condition\": {\"expression\":\"attribute_not_exists(#id)\",\"expressionNames\":{\"#id\":\"id\"}}\n}\n"
}
为保存操作记录的 ResponseMapping
{
"logType": "ResponseMapping",
"path": [
"createAccountMember"
],
"fieldName": "createAccountMember",
"resolverArn": "<redacted>",
"requestId": "<redacted>",
"context": {
"arguments": {
"input": {
"id": "<redacted>",
"userID": "<redacted>",
"accountID": "<redacted>",
"membershipStatus": "active",
"groupsEnrolledIn": [
"<redacted>",
"<redacted>",
"<redacted>"
],
"recordOwner": "<redacted>",
"createdAt": "2020-08-25T05:11:10.917Z",
"updatedAt": "2020-08-25T05:11:10.917Z",
"__typename": "AccountMember"
}
},
"result": {
"accountID": "<redacted>",
"createdAt": "2020-08-25T05:11:10.917Z",
"recordOwner": "<redacted>",
"__typename": "AccountMember",
"id": "<redacted>",
"membershipStatus": "active",
"userID": "<redacted>",
"groupsEnrolledIn": [
"<redacted>",
"<redacted>",
"<redacted>"
],
"updatedAt": "2020-08-25T05:11:10.917Z"
},
"stash": {},
"outErrors": []
},
"fieldInError": false,
"errors": [],
"parentType": "Mutation",
"graphQLAPIId": "<redacted>",
"transformedTemplate": "{\"accountID\":\"<redacted>\",\"createdAt\":\"2020-08-25T05:11:10.917Z\",\"recordOwner\":\"<redacted>\",\"__typename\":\"AccountMember\",\"id\":\"<redacted>\",\"membershipStatus\":\"active\",\"userID\":\"<redacted>\",\"groupsEnrolledIn\":[\"<redacted>\",\"<redacted>\",\"<redacted>\"],\"updatedAt\":\"2020-08-25T05:11:10.917Z\"}\n"
}
这是为列表操作记录的请求映射。你可以看到consistentRead=true
{
"logType": "RequestMapping",
"path": [
"listAccountMembers"
],
"fieldName": "listAccountMembers",
"resolverArn": "<redacted>",
"requestId": "<redacted>",
"context": {
"arguments": {
"filter": {
"userID": {
"eq": "<redacted>"
}
}
},
"stash": {},
"outErrors": []
},
"fieldInError": false,
"errors": [],
"parentType": "Query",
"graphQLAPIId": "<redacted>,
"transformedTemplate": " \n{\"version\":\"2018-05-29\",\"limit\":100,\"consistentRead\":true,\"filter\":{\"expression\":\"(#userID = :userID_eq)\",\"expressionNames\":{\"#userID\":\"userID\"},\"expressionValues\":{\":userID_eq\":{\"S\":\"<redacted>\"}}},\"operation\":\"Scan\"}"
}
这是记录的 responseMapping。您可以看到结果是一个空数组 ( items:[]
),即使之前已经添加了记录并且我们已经consistentRead=true
为查询指定了该记录。
{
"logType": "ResponseMapping",
"path": [
"listAccountMembers"
],
"fieldName": "listAccountMembers",
"resolverArn": "<redacted>",
"requestId": "<redacted>",
"context": {
"arguments": {
"filter": {
"userID": {
"eq": "<redacted>"
}
}
},
"result": {
"items": [],
"nextToken": "<redacted>",
"scannedCount": 100
},
"stash": {},
"outErrors": []
},
"fieldInError": false,
"errors": [],
"parentType": "Query",
"graphQLAPIId": "<redacted>",
"transformedTemplate": "\n{\"items\":[],\"nextToken\":\"<redacted>",\"scannedCount\":100,\"startedAt\":null}\n"
}
我还能错过什么?
更新02
我找到了可能的原因。这是因为我不熟悉 DynamoDB 的工作方式。查询或扫描操作按键获取结果。在这种情况下,不涉及密钥,因此它会考虑到所有记录的限制。在我的情况下,它是 100,然后它应用过滤器。因此,如果添加的记录不在前 100 个结果中,除非我通过分页(不适合特定需要),否则它无法找到它。
TL;DR:我将查询更改为使用@key 指令,并将 userID 作为关键字段,问题已经解决,因为 que 字段是 GSI,并且我希望使用此类分区检索的记录数远低于 100 限制. 完成撤消之前所做的调整后,我会将此添加为答案的一部分。