AWS Appsync Batch Resolver

Некоторое время борясь с этим, я изменил имя запроса для вопроса на 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
     ]
   }
 }
}

введите описание изображения здесь

Как вы можете видеть на изображении, ключ первичного раздела - это устройство в таблице показаний. Я смотрю журналы, и у меня есть следующие

введите описание изображения здесь

Извините, если вы не можете прочитать журнал, в нем в основном говорится, что есть необработанные ключи

и следующее сообщение об ошибке

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

Я предполагаю, что мое отображение не совсем правильное, и я передаю показания в качестве ключей?

Любая помощь очень ценится


person hounded    schedule 29.08.2018    source источник


Ответы (3)


Нет, вы можете использовать пакетные преобразователи, если у вас есть первичный ключ сортировки. Ошибка в вашем примере заключается в том, что вы не предоставили преобразователю первичный ключ сортировки.

Этот код должен предоставлять «время», а также «устройство», потому что вам нужно и то, и другое, чтобы полностью указать первичный ключ.

#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, а не пакетное получение.

person mparis    schedule 29.08.2018

Вы правы, предоставленный вами шаблон сопоставления запросов не соответствует первичному ключу в таблице readings. BatchGetItem ожидает, что keys будет первичными ключами, однако вы передаете только хэш-ключ.

Чтобы вызов BatchGetItem был успешным, вы должны передать и хэш, и ключ сортировки, поэтому в данном случае атрибуты device и time.

Может быть, Query в таблице readings было бы более подходящим?

person Tinou    schedule 29.08.2018
comment
Спасибо за ответ, и вы, и mparis исправили меня, я собираюсь дать ответ mparis, поскольку он привел пример. Еще раз спасибо, ребята! Привет, дополнительные реквизиты, если вы можете сказать мне, есть ли какое-либо преимущество в наличии преобразователя VTL appsync по сравнению с преобразователем лямбда - person hounded; 29.08.2018
comment
Привет, Тиноу, ты видишь, как я перебираю, а затем расширяю список в моей лямбда-функции, как бы мне это сделать с помощью VTL в запросе? Я задам отдельный вопрос - person hounded; 30.08.2018
comment
не беспокойтесь, та же команда! Если вы используете преобразователь Lambda, вы вводите промежуточный шаг для запроса таблицы DynamoDB. Жизненный цикл вашего запроса будет AppSync - ›Lambda -› DynamoDB vs AppSync - ›DynamoDB, если вы используете преобразователь DynamoDB в AppSync. Это означает, что общая задержка вашего запроса GraphQL увеличится. Для более сложных рабочих процессов использование решателя Lambda должно дать вам больше контроля. - person Tinou; 30.08.2018
comment
Потрясающе спасибо, Тиноу, очень признателен за время, потраченное на ответ. Я задал вопрос здесь stackoverflow.com/questions/52086862/aws- appsync-query-resolver Возможно ли то, о чем я спрашиваю? - person hounded; 30.08.2018

Значит, у вас не может быть пакетного преобразователя, если у вас есть первичный ключ сортировки ?!

Итак, ответ заключался в том, чтобы создать лямбда-функцию и закрепить ее в качестве моего преобразователя.

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
person hounded    schedule 29.08.2018