AWS Appsync批次解析器

时间:2018-08-29 05:06:46

标签: amazon-web-services graphql aws-appsync resolver

暂时为此苦苦挣扎,applogies我将问题的查询名称更改为getDeviceReadings,我一直在使用getAllUserDevices(对不起,造成任何混淆)

type Device {
   id: String
   device: String!
}

type Reading {
   device: String
   time: Int
}

type PaginatedDevices {
   devices: [Device]
   readings: [Reading]
   nextToken: String
}

type Query {
   getDevicesReadings(nextToken: String, count: Int): PaginatedDevices
}

然后我在查询getDevicesReadings上有一个解析器,该解析器可以正常工作,并返回用户到目前为止一切正常的所有设备

{
"version": "2017-02-28",
"operation": "Query",
"query" : {
  "expression": "id = :id",
    "expressionValues" : {
      ":id" : { "S" : "${context.identity.username}" }
    }
}
#if( ${context.arguments.count} )
    ,"limit": ${context.arguments.count}
#end
#if( ${context.arguments.nextToken} )
    ,"nextToken": "${context.arguments.nextToken}"
#end
}

现在我想根据源结果返回设备拥有的所有读数,因此我在getDevicesReadings / readings上有一个解析器

#set($ids = [])
#foreach($id in ${ctx.source.devices})
  #set($map = {})
  $util.qr($map.put("device", $util.dynamodb.toString($id.device)))
  $util.qr($ids.add($map))
#end

{
"version" : "2018-05-29",
"operation" : "BatchGetItem",
 "tables" : {
    "readings": {
        "keys": $util.toJson($ids),
        "consistentRead": true
    }
  }
}

具有类似..

的响应映射
$utils.toJson($context.result.data.readings)

我运行查询

query getShit{
  getDevicesReadings{
    devices{
      device
     }
    readings{
      device
      time
    }
  }
}

这将返回以下结果

{
  "data": {
    "getAllUserDevices": {
     "devices": [
       {
         "device": "123"
       },
       {
         "device": "a935eeb8-a0d0-11e8-a020-7c67a28eda41"
       }
     ],
     "readings": [
       null,
       null
     ]
   }
 }
}

enter image description here

您可以在图像上看到,主分区键是读数表上的设备,我查看了日志,并且具有以下内容

enter image description here

对不起,如果您无法阅读日志,它基本上会说有未处理的键

以及以下错误消息

"message": "The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 0H21LJE234CH1GO7A705VNQTJVVV4KQNSO5AEMVJF66Q9ASUAAJG)",

我猜我的映射有些不正确,我将读数作为键传递给了我?

任何帮助表示赞赏

3 个答案:

答案 0 :(得分:2)

您是正确的,您提供的请求映射模板与readings表上的主键不匹配。 BatchGetItem期望keys是主键,但是您仅传递哈希键。

要成功进行BatchGetItem调用,您必须同时传递哈希键和排序键,因此,在这种情况下,必须同时传递devicetime属性。

也许Query表上的readings更合适?

答案 1 :(得分:1)

否,拥有主排序键时,您绝对可以使用批处理解析器。您的示例中的错误是您没有向解析器提供主排序键。

此代码需要同时提供“时间”和“设备”,因为您需要同时完全指定主键。

#set($ids = [])
#foreach($id in ${ctx.source.devices})
  #set($map = {})
  $util.qr($map.put("device", $util.dynamodb.toString($id.device)))
  $util.qr($ids.add($map))
#end

您应该有类似的东西:

#set($ids = [])
#foreach($id in ${ctx.source.devices})
  #set($map = {})
  # The tables primary key is made up of "device" AND "time"
  $util.qr($map.put("device", $util.dynamodb.toString($id.device)))
  $util.qr($map.put("time", $util.dynamodb.toString($id.time)))
  $util.qr($ids.add($map))
#end

如果要获取许多共享相同“设备”值但具有不同“时间”值的记录,则需要使用DynamoDB查询操作,而不是批量获取。

答案 2 :(得分:0)

因此,当您具有主排序键时,您将无法使用批处理解析器?

所以答案是创建一个lambda函数并将其作为我的解析器

import boto3
from boto3.dynamodb.conditions import Key

def lambda_handler(event, context):

   list = []
   for device in event['source']['devices'] :
       dynamodb = boto3.resource('dynamodb')
       readings  = dynamodb.Table('readings')
       response = readings.query(
           KeyConditionExpression=Key('device').eq(device['device'])
       )
       items = response['Items']
       list.extend(items)
   return list