Ошибка при использовании getItem с DynamoDB с библиотекой узла aws-sdk - PullRequest
1 голос
/ 14 марта 2019

Следующий код выдает это сообщение об ошибке при попытке доступа к моей таблице AWS DynamoDB.Таблица называется клиенты, а столбец называется электронная почта со значением «james@gmail.com».Я скопировал этот код прямо из примеров AWS, доступных здесь https://github.com/awsdocs/aws-doc-sdk-examples. Что-то я делаю не так?Я потратил дни на это, пробуя разные вещи: - (

Любая помощь приветствуется. Спасибо,

Сообщение об ошибке

{"message":"Expected params.Key to be a map","code":"InvalidParameterType","time":"2019-03-13T23:05:59.231Z"}

Код NodeJs

const express = require('express')
const app = express()
const port = 8080
var AWS = require('aws-sdk');

app.get('/test', (req, res) => {

    // Set the region 
    AWS.config.update({region: 'eu-west-1'});

    // Create DynamoDB document client
    var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

    var key = { email: 'james@gmail.com' };

    ddb.getItem({
       TableName: 'customers',
       Key: key
    }, function(err, data) {
        if (err) {
          res.send(err);
        }
        else {
          res.send(data);
        }
    });

});

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Таблица DynamoDB

enter image description here

Еще одна попытка Я также получил это сообщение об ошибке

{"message":"There were 20 validation errors:\n* InvalidParameterType: Expected params.Key['email'] to be a structure\n* UnexpectedParameter: Unexpected key '0' found in params.Key['email']\n* UnexpectedParameter: Unexpected key '1' found in params.Key['email']\n* UnexpectedParameter: Unexpected key '2' found in params.Key['email']\n* UnexpectedParameter: Unexpected key '3' found in params.Key['email']\n* UnexpectedParameter: Unexpected key '4' found in params.Key['email']\n* UnexpectedParameter: Unexpected key '5' found in params.Key['email']\n* UnexpectedParameter: Unexpected key '6' found in 

Обновление

 var key = { email: 'james@gmail.com' };

    ddb.getItem({
       TableName: 'customers',
       Key: key
    }, function(err, data) {
        if (err) {
          res.send(err);
        }
        else {
          res.send(data);
        }
    });

Обновление

const express = require('express')
const app = express()
const port = 8080
var AWS = require('aws-sdk');

app.get('/test', (req, res) => {

    AWS.config.update({region: 'eu-west-1'});
    var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

    var params = {
      TableName: 'customers',
      Key: {
        'email': {S: 'james@gmail.com'}
      },
    };

    ddb.getItem(params, function(err, data) {
        if (err) {
            res.send(err);
        } else {
            res.send(data);
        }
    });

});

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Результат ошибки

{"message":"The provided key element does not match the schema","code":"ValidationException","time":"2019-03-14T19:26:13.602Z","requestId":"EIGKLLNEJR2DKSET6787JHQLC7VV4KQNSO5AEMVJF66Q9ASUAAJG","statusCode":400,"retryable":false,"retryDelay":46.10177725769697}

Ответы [ 2 ]

2 голосов
/ 14 марта 2019

2-е РЕДАКТИРОВАНИЕ : Я полностью упустил, что вы не используете DocumentClient (как указал Владислав Уленко), поэтому обновленный ответ ниже для полноты.


У вас есть два варианта:

Первая опция использовать сервисный объект DynamoDB с методом getItem следующим образом:

...
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

var params = {
  TableName: 'customers',
  Key: {
    'email': {S: 'james@gmail.com'} . // <-- pay attention to data type 'S'  
  },
};

ddb.getItem(params, function(err, data) {
    if (err) {
        res.send(err);
    } else {
        res.send(data);
    }
});

DynamoDB Типы данных (значения атрибута) указаны здесь (ищите таблицу Marshalling / Unmarshalling mapping.

Второй вариант должен использовать DocumentClient. В этом сценарии вам не нужно беспокоиться о маршалинге и немаршалинге данных запроса / ответа (значение DynamoDB для / из типа JavaScript). В этом случае ваш код выглядит так:

...

var docClient = new AWS.DynamoDB.DocumentClient({apiVersion: '2012-08-10'});


var params = {
 TableName: 'customers',
 Key: {'email': 'james@gmail.com'}
};

docClient.get(params, function (err, data) {
    if (err) {
        res.send(err);
    } else {
        res.send(data);
    }
});
...

Я бы предложил использовать DocumentClient вместо DynamoDB' getItem`, поскольку он полностью обрабатывает все преобразования данных!

Если вы этого не сделаете, ТАКЖЕ вам необходимо позаботиться о типах данных ответа, например:

data.Items.forEach(function(element, index, array) {
      console.log(element.FristName.S + " " + element.LastName.S);
    });

не уверен, хочешь ли ты этого


3-е РЕДАКТИРОВАНИЕ : Теперь, когда вы сделали вышеупомянутое, вы получаете ошибку:

"The provided key element does not match the schema"

Это означает, что ключ, который вы использовали, не совпадает с ключом, определенным в вашей схеме, опять же из документации :

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

Проверьте ключи в деталях таблицы (пример) enter image description here

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

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

1 голос
/ 14 марта 2019

Вы используете DynamoDB как DocumentClient.Если вы переключите свою строку var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'}); на var docClient = new AWS.DynamoDB.DocumentClient();, ваши запросы будут работать.

С простым экземпляром класса DynamoDB вы также должны указать типы данных ваших ключей вручную, вы можете найти ссылку на типы данных здесь .Однако в случае экземпляра класса DocumentClient этот класс отвечает за сопоставление данных между типами JS и типами DynamoDB.Вы можете найти эту информацию здесь в разделе Обзор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...