【问题标题】:AppSync BatchPutItem not saving itemsAppSync BatchPutItem 不保存项目
【发布时间】:2019-12-30 04:34:03
【问题描述】:

我正在尝试使用 AppSync 将一些项目批量放入 DynamoDB。当我调用解析器时,它不会引发任何错误,但不会将任何内容保存到数据库中。

架构

type BoxScore @model {
  id: ID!
  userId: String!
  gameVariant: String!
  complete: Boolean!
  failFact: BoxScoreFact @connection
  totalCorrect: Int!
}

type BoxScoreFact @model {
  id: ID!
  left: Int!
  right: Int!
  gameVariant: String!
  timestamp: Int!
  correct: Boolean!
}

input BatchAddCreateBoxScoreFactInput {
  id: ID
  left: Int!
  right: Int!
  gameVariant: String!
  timestamp: Int!
  correct: Boolean!
  boxScoreFactBoxScoreId: ID!
}

IAM 角色:

        "Effect": "Allow",
        "Action": [
            "dynamodb:DeleteItem",
            "dynamodb:GetItem",
            "dynamodb:PutItem",
            "dynamodb:Query",
            "dynamodb:Scan",
            "dynamodb:UpdateItem",
            "dynamodb:BatchGetItem",
            "dynamodb:BatchWriteItem"
        ],

解析器

#set($factsdata = [])
#foreach($item in ${ctx.args.facts})
    $util.qr($factsdata.add($util.dynamodb.toMapValues($item)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "TABLENAME": $utils.toJson($factsdata)
    }
}

从 AppSync 游乐场调用:

响应映射模板:

  #if($ctx.error)
      ## Append a GraphQL error for that field in the GraphQL response
      $utils.error($ctx.error.message, $ctx.error.message)
  #end

  {
      "boxScoreFacts": $util.toJson({"res": "no error", "ctx": $ctx}),
  }

功能测试运行的输出模板:

DynamoDB 表

其中TABLENAME 设置为等于显示在 DDB 控制台中的 DynamoDB 表名称。所以像 BoxScoreFact-woieieie99392-prod 这样的东西。

表格始终为空,响应为空。这几乎是直接从example from the docs 中提取出来的。另外,我应该注意,使用正常的 create graphql 函数放置一个项目确实会将一个项目放置到预期的表中。

我在这里错过了什么?

【问题讨论】:

  • 您能提供您的响应映​​射模板吗?
  • @Neill 添加了。如果响应映射模板无效,是否会阻止 put 完全发生,即不保存到表中?
  • 您可以尝试为 AppSync 启用日志记录,看看日志中是否有任何有趣的内容。您的角色还有哪些 IAM 权限?
  • @Phil,不是真的,但您可能看不到从 DynamoDB 返回的错误,您能否尝试引发错误而不是附加错误?
  • @Neill 显示解析器模板的 $ctx 输出的屏幕截图被截断,显然不可复制,错误:null 和 outError:[]。所以看起来没有什么问题。另外,我应该注意,使用正常的 create graphql 函数放置一个项目确实会将一个项目放置到预期的表中。

标签: amazon-web-services amazon-dynamodb graphql aws-appsync vtl


【解决方案1】:

Appsync 的 lambda 函数通过 Serverless Appsync 插件调用,在此角色中,旧版本中缺少 BatchWriteItem。 在您的 package.json 文件中,尝试将插件版本更改为最新版本或修复此问题的 GitHub 版本。

这应该可以解决它:

"devDependencies": {
   ....
   "serverless-appsync-plugin": "^1.1.0"
   ....
}

"devDependencies": {
   ....
   "serverless-appsync-plugin": "https://github.com/sid88in/serverless-appsync-plugin.git#e33b5cfd"
   ....
}

【讨论】:

  • 不需要使用额外的包来让它工作
  • 好的,我遇到了和你一样的问题,所以我假设你会使用这个包。这是我花了很长时间才找到的解决方案。
【解决方案2】:

看起来强制的id 没有在您的变量之间传递。您可以尝试在解析器中自动设置它:

#set($factsdata = [])
#foreach($item in ${ctx.args.facts})
    $util.qr($item.put("id", $util.defaultIfNullOrBlank($item.id, $util.autoId())))
    $util.qr($factsdata.add($util.dynamodb.toMapValues($item)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "TABLENAME": $utils.toJson($factsdata)
    }
}

【讨论】:

    【解决方案3】:

    我的解决方案是在 IAM 角色 "dynamodb:BatchGetItem" and "dynamodb:BatchWriteItem" 中包含批处理权限。似乎默认情况下不包含此操作。

    最终的 json 政策

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "dynamodb:DeleteItem",
                    "dynamodb:GetItem",
                    "dynamodb:PutItem",
                    "dynamodb:Query",
                    "dynamodb:Scan",
                    "dynamodb:UpdateItem",
                    "dynamodb:BatchGetItem",
                    "dynamodb:BatchWriteItem"
                ],
                "Resource": [
                    "arn:aws:dynamodb:<region>:<account_id>:table/<TableName>",
                    "arn:aws:dynamodb:<region>:<account_id>:table/<TableName>/*"
                ]
            }
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 2019-01-01
      • 2020-03-09
      • 2020-03-13
      • 1970-01-01
      • 2019-02-16
      • 2018-06-29
      • 1970-01-01
      • 2018-12-26
      • 2014-09-05
      相关资源
      最近更新 更多