DynamoDB и DocumentClient дают разные значения ключа?

#node.js #amazon-web-services #amazon-dynamodb

#node.js #amazon-веб-сервисы #amazon-dynamodb

Вопрос:

Я пытаюсь использовать aws DynamoDB и прочитал несколько руководств по созданию, чтению и обновлению элементов в таблицах. Но по какой-то причине я получаю разные значения ключей при использовании DocumentClient и DynamoDB; а именно, значения ключей немного отличаются.

В моем коде у меня есть:

 const dynamodb = new AWS.DynamoDB();
let docClient = new AWS.DynamoDB.DocumentClient();

async function returnServers(){
    await dynamodb.scan({TableName: 'pixelbot_servers'}, function(err, data) {
        if (err) {
            console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log("dynamodb scan succeeded:", JSON.stringify(data, null, 2));
        }
    });
    
    await docClient.scan({TableName: 'pixelbot_servers'}, function(err, data) {
        if (err) {
            console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
        } else {
            console.log("docClient scan succeeded:", JSON.stringify(data, null, 2));
        }
    });
 

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

 docClient scan succeeded: {
  "Items": [
    {
      "server_id": 558952579627876350,
      "getrole_post_id": 797525306164510700
 

и

 dynamodb scan succeeded: {
  "Items": [
    {
      "server_id": {
        "N": "558952579627876353"
      },
      "getrole_post_id": {
        "N": "797525306164510740"
 

Мне просто интересно, почему я получаю разные значения, когда использую только одну таблицу. Значения, которые, как правило, являются правильными, поступают из dynamodb вместо docClient, который, как я вижу, использует большинство людей.

РЕДАКТИРОВАТЬ: я изменил типы данных в таблице на строки, поэтому я получу согласованные результаты как от docclient, так и от dynamodb, все еще не уверен, почему значения отличались при использовании datatype: number . Может быть неправильное преобразование из int в bigint или что-то подобное. Не уверен.

Комментарии:

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

2. Меня беспокоит не порядок, а результаты. Я даже не знаю, откуда берутся результаты docClients, потому что у меня есть только одна таблица с теми же результатами, что и те, которые возвращает dynamodb.

3. Я не понимаю, где вы говорите, что ключи одинаковы — какое поле является ключевым в ваших результатах? потому что и server_id, и getrole_post_id имеют разные значения.

4. Вы можете увидеть ограничения по типу данных здесь: docs.aws.amazon.com/amazondynamodb/latest/developerguide /…

5. Сколько элементов в этой таблице? Достаточно ли мало, чтобы все они были возвращены при одном сканировании? Если нет, вам нужно разбить на страницы по мере необходимости, агрегировать результаты, а затем, наконец, отсортировать и сравнить результаты.

Ответ №1:

Это предел узла. DocumentClients сопоставляет типы Dynamodb с типами узлов, в данном случае N -> number . Значение превышает точность, поэтому вы теряете эту информацию во время синтаксического анализа. DocumentClient не поддерживает такой случай, вам нужно написать свой собственный синтаксический анализ для Dynamodb -> Типы узлов

Комментарии:

1. Согласно документам aws, NUMBER имеет точность 38 цифр, но мои ключи ниже 38 цифр, поэтому я все еще не уверен, почему это не точно. docs.aws.amazon.com/amazondynamodb/latest/developerguide /…

2. Точно, Dynamodb поддерживает такую точность, но номер узла — нет.

Ответ №2:

Проблема здесь, по-видимому, заключается в сочетании реализации float в Python и выбора boto3 float для представления числовых атрибутов.

В Python, если вы инициализируете переменную, чтобы 558952579627876353 затем распечатать ее, она имеет значение 558952579627876353 . Однако, если вы инициализируете переменную значением с плавающей запятой 558952579627876353.0 , а затем печатаете ее, она имеет значение 5.5895257962787635e 17 или эффективно 558952579627876350 . В частности, после этого он потерял точность ...635 , и все остальное становится равным нулю.

Аналогично, 797525306164510740.0 становится 7.975253061645107e 17 , эффективно 797525306164510700 .

Я бы рекомендовал (как и вы) использовать строки для идентификаторов. Также см. boto/boto3/issues / 665 для контекста.