DynamoDB JavaScript SDK v2 v3: gestione delle tabelle – 2

Spread the love

In questo articolo eseguiremo e analizzeremo il codice scaricato dall’articolo precedente, creeremo, elimineremo e otterremo l’elenco delle tabelle.

DynamoDB JavaScript SDK v2 and v3 manage tables
DynamoDB JavaScript SDK v2 and v3 manage tables

Tutti gli sdk di AWS sono disponibili tramite npm dal repository nodejs, quindi quando esegui npm i sulla cartella con il package.json ottieni tutto il codice sorgente necessario per eseguire gli scripts nel reposotory github.

Crea una semplice tabella

Puoi creare una tabella direttamente dalla console all’indirizzo (cambia regione la tua):

https://eu-west-1.console.aws.amazon.com/dynamodb/home?region=eu-west-1#tables:

Poi fai clic su con crea tabella

DynamoDB Crea tabella dall'AWS console
DynamoDB Crea tabella dall’AWS console

è necessario aggiungere il nome della tabella e una chiave di partizione, aggiungeremo anche una chiave di ordinamento.

SDK v2

Il metodo predefinito per interrogare la DynamoDB è quello di utilizzare chiamate asincrone, ma è possibile utilizzare la promise() per utilizzare  l’async, await, per cui la richiesta diventa sincrono.

Le promises possono essere utilizzare anche per eseguire in parallelo una serie di comandi.

Per prima cosa faremo una semplice creazione con una funzione di callback, prestare attenzione a impostare la regione corretta nello script .

Come puoi vedere, importeremo l’intero pacchetto aws-sdk, quindi lo useremo per eseguire tutti i comandi.

Il comando per la creazione è createTable e il primo parametro è l’informazione necessaria per la creazione della tabella, il secondo è la funzione di callback.

/*
 * DynamoDB Script Examples
 * Create table in
 * DB of selected region in AWS.config.update
 *
 * AUTHOR:  Renzo Mischianti https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2020 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 *
 */

var AWS = require("aws-sdk");

AWS.config.update({
    apiVersion: '2012-08-10',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // // accessKeyId default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // accessKeyId: "9oiaf7",
    // // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // secretAccessKey: "yz5i9"
});

var ddb = new AWS.DynamoDB();

console.log("Start script!");

var params = {
    TableName: 'TestTableMischianti',
    KeySchema: [ // The type of of schema.  Must start with a HASH type, with an optional second RANGE.
        { // Required HASH type attribute
            AttributeName: 'ItemId',
            KeyType: 'HASH',
        },
        {
            AttributeName: 'ItemName',
            KeyType: 'RANGE'
        }
    ],
    AttributeDefinitions: [ // The names and types of all primary and index key attributes only
        { // Type attribute
            AttributeName: 'ItemId',
            AttributeType: 'S',
        },
        {
            AttributeName: 'ItemName',
            AttributeType: 'S'
        }
        // ... more attributes ...
    ],
    ProvisionedThroughput: { // required provisioned throughput for the table
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1,
    },
};

ddb.createTable(params, function(err, data) {
    if (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred

        console.log('message --> ', err.message);
    } else {
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response
    }
});
console.log("End script!");

Questa tabella ha 2 chiavi:

  • ItemId È una chiave di partizione , questo tipo di chiavi sono obbligatorie nelle query e puoi usarle per creare un gruppo di dati da interrogare (partizionare= o come chiave primaria;
  • ItemName È simile a un indice utilizzato per ottenere dei dati dalla partizione.

ma capiremo la differenza pratica quando vedremo degli esempi di query.

Per eseguire questo script vai nella cartella dynamodb-examples\jsv2 e esegui node table_create.js

Il risultato della console dello script è

D:\Projects\AlexaProjects\dynamodb-management\dynamodb-examples\jsv2>node table_create.js
Start script!
End script!
Full success response {
  "TableDescription": {
    "AttributeDefinitions": [
      {
        "AttributeName": "ItemId",
        "AttributeType": "S"
      },
      {
        "AttributeName": "ItemName",
        "AttributeType": "S"
      }
    ],
    "TableName": "TestTableMischianti",
    "KeySchema": [
      {
        "AttributeName": "ItemId",
        "KeyType": "HASH"
      },
      {
        "AttributeName": "ItemName",
        "KeyType": "RANGE"
      }
    ],
    "TableStatus": "CREATING",
    "CreationDateTime": "2021-01-08T21:17:41.573Z",
    "ProvisionedThroughput": {
      "NumberOfDecreasesToday": 0,
      "ReadCapacityUnits": 1,
      "WriteCapacityUnits": 1
    },
    "TableSizeBytes": 0,
    "ItemCount": 0,
    "TableArn": "arn:aws:dynamodb:eu-west-1:827664048987:table/TestTableMischianti",
    "TableId": "8b0a5a62-2955-4bce-ae08-5ed8dea554ea"
  }
}

Puoi vedere che Start script!End script! vengono eseguiti immediatamente, poi arriva la risposta, questo perché l’esecuzione del callback è asincrona, quindi prima è stato eseguito tutto il codice, poi quando la chiamata REST ha risposto è stata chiamata la callback.

Una soluzione migliore (l’impostazione predefinita in v3) è quella di utilizzare async, await, con questo metodo il codice si interrompe fino a quando non viene fornita una risposta.

Per eseguire questo script vai nella cartella dynamodb-examples\jsv2e avvia node table_create_async_await.js

/*
 * DynamoDB Script Examples
 * Create table in
 * DB of selected region in AWS.config.update
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 *
 */

var AWS = require("aws-sdk");

AWS.config.update({
    apiVersion: '2012-08-10',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // // accessKeyId default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // accessKeyId: "9oiaf7",
    // // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // secretAccessKey: "yz5i9"
});

var ddb = new AWS.DynamoDB();

(async function () {
    console.log("Start script!");

    var params = {
        TableName: 'TestTableMischianti4',
        KeySchema: [ // The type of of schema.  Must start with a HASH type, with an optional second RANGE.
            { // Required HASH type attribute
                AttributeName: 'ItemId',
                KeyType: 'HASH',
            }
        ],
        AttributeDefinitions: [ // The names and types of all primary and index key attributes only
            { // Type attribute
                AttributeName: 'ItemId',
                AttributeType: 'S',
            }
            // ... more attributes ...
        ],
        ProvisionedThroughput: { // required provisioned throughput for the table
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    };

    try {
        const data = await ddb.createTable(params).promise();
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response
    }catch (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred

        console.log('message --> ', err.message);
    }

    console.log("End script!");

})();

Ho inglobato tutto il codice con la funzione async, e ho messo l’await sulla promise della createTable, e il risultato in console ora è

D:\Projects\AlexaProjects\dynamodb-management\dynamodb-examples\jsv2>node table_create_async_await.js
Start script!
Full success response {
  "TableDescription": {
    "AttributeDefinitions": [
      {
        "AttributeName": "ItemId",
        "AttributeType": "S"
      }
    ],
    "TableName": "TestTableMischianti4",
    "KeySchema": [
      {
        "AttributeName": "ItemId",
        "KeyType": "HASH"
      }
    ],
    "TableStatus": "CREATING",
    "CreationDateTime": "2021-01-15T08:04:55.174Z",
    "ProvisionedThroughput": {
      "NumberOfDecreasesToday": 0,
      "ReadCapacityUnits": 1,
      "WriteCapacityUnits": 1
    },
    "TableSizeBytes": 0,
    "ItemCount": 0,
    "TableArn": "arn:aws:dynamodb:eu-west-1:827664048987:table/TestTableMischianti4",
    "TableId": "fd1e8c0e-efbf-4fdd-bbcd-09ffc28b3c00"
  }
}
End script!

Ora Start Script! è all’inizio e End Script! è alla fine, quindi l’esecuzione è avvenuta in maniera sincrona.

SDK v3

La nuova versione dell’SDK usa la chiamata sincrona come metodo predefinito per l’esecuzione, ma puoi usare anche l’asincrona (ma sconsigliato), esamineremo tutti i tipi di chiamata della versione v3 quando vedremo il metodo di aggiunta dell’elemento.

Imposta la regione corretta del tuo account.

Per eseguire questo script vai nella cartella dynamodb-examples\jsv3 e avvia node table_create_async_await.js

/*
 * DynamoDB Script Examples v3
 * Create table with DynamoDB async await
 * DB of selected region in configDynamoDB
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 *
 */

const { DynamoDBClient, CreateTableCommand  } = require("@aws-sdk/client-dynamodb");
const configDynamoDB = {
    version: 'latest',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // credentials: {
    //     // accessKeyId default can be used while using the downloadable version of DynamoDB.
    //     // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    //     accessKeyId: "9oiaf7",
    //     // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    //     // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    //     secretAccessKey: "yz5i9"
    //
    // }
};

const dbClient = new DynamoDBClient(configDynamoDB);

(async function () {
    console.log("Start script!");

    var params = {
        TableName: 'TestTableMischianti',
        KeySchema: [ // The type of of schema.  Must start with a HASH type, with an optional second RANGE.
            { // Required HASH type attribute
                AttributeName: 'ItemId',
                KeyType: 'HASH',
            },
            {
                AttributeName: 'ItemName',
                KeyType: 'RANGE'
            }
        ],
        AttributeDefinitions: [ // The names and types of all primary and index key attributes only
            { // Type attribute
                AttributeName: 'ItemId',
                AttributeType: 'S',
            },
            {
                AttributeName: 'ItemName',
                AttributeType: 'S'
            }
            // ... more attributes ...
        ],
        ProvisionedThroughput: { // required provisioned throughput for the table
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    };

    try {
        const command = new CreateTableCommand(params);
        const data = await dbClient.send(command);
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response
    }catch (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred
    }

    console.log("End script!");
})();

In questo script i singoli comandi sono separati per garantire l’importazione modulare

const { DynamoDBClient, CreateTableCommand  } = require("@aws-sdk/client-dynamodb");

Puoi anche chiamare questi comandi in un unico passaggio con l’istanza DynamoDB, puoi chiamare db.createTable ma è sconsigliato perché devi importare tutti i pacchetti e le funzionalità di modularizzazione saranno perse.

Il risultato della console diventa.

D:\Projects\AlexaProjects\dynamodb-management\dynamodb-examples\jsv3>node table_create_async_await.js
Start script!
Full error response {
  "name": "ResourceInUseException",
  "$fault": "client",
  "$metadata": {
    "httpStatusCode": 400,
    "httpHeaders": {
      "server": "Server",
      "date": "Fri, 15 Jan 2021 21:26:36 GMT",
      "content-type": "application/x-amz-json-1.0",
      "content-length": "122",
      "connection": "keep-alive",
      "x-amzn-requestid": "6THN0HTAEUC6D4RC57LQ4UPQ1RVV4KQNSO5AEMVJF66Q9ASUAAJG",
      "x-amz-crc32": "2952303443"
    },
    "requestId": "6THN0HTAEUC6D4RC57LQ4UPQ1RVV4KQNSO5AEMVJF66Q9ASUAAJG",
    "attempts": 1,
    "totalRetryDelay": 0
  }
}
End script!

È possibile controllare Start script!End script! per verificare che lo script sia sincrono.

Verifica sulla console AWS.

DynamoDB Tabella creata
DynamoDB Tabella creata

Puoi verificare la creazione della tabella nella console AWS del DynamoDB al link (fai attenzione alla regione, imposta quella corretta)

https://eu-west-1.console.aws.amazon.com/dynamodb/home?region=eu-west-1#tables:

Se fai clic sulla tabella nell’elenco puoi ottenere maggiori informazioni.

Elimina tabella

Lo script di eliminazione è abbastanza semplice, per la v2 mostrerò la versione sincrona e asincrona. Presta attenzione alla regione.

SDK v2

Qui lo script nella versione asincrona, che puoi eseguire con node table_create.js nella cartella su v2

/*
 * DynamoDB Script Examples
 * Delete table in
 * DB of selected region in AWS.config.update
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 */

var AWS = require("aws-sdk");

AWS.config.update({
    apiVersion: '2012-08-10',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // // accessKeyId default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // accessKeyId: "9oiaf7",
    // // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // secretAccessKey: "yz5i9"
});

var ddb = new AWS.DynamoDB();

console.log("Start script!");

var params = {
    TableName: 'TestTableMischianti',
};
ddb.deleteTable(params, function(err, data) {
    if (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred

        console.log('message --> ', err.message);
    } else {
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response
    }
});
console.log("End script!");

Per tutti gli script l’unico parametro necessario è TableName, qui il risultato della console.

Start script!
End script!
Full success response {
  "TableDescription": {
    "TableName": "TestTableMischianti",
    "TableStatus": "DELETING",
    "ProvisionedThroughput": {
      "NumberOfDecreasesToday": 0,
      "ReadCapacityUnits": 1,
      "WriteCapacityUnits": 1
    },
    "TableSizeBytes": 0,
    "ItemCount": 0,
    "TableArn": "arn:aws:dynamodb:eu-west-1:XXXXXXXXXXXXX:table/TestTableMischianti",
    "TableId": "8b0a5a62-2955-4bce-ae08-5ed8dea554ea"
  }
}

Ora la versione sincrona (node table_create_async_await.js).

/*
 * DynamoDB Script Examples
 * Delete table in
 * DB of selected region in AWS.config.update
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 */

var AWS = require("aws-sdk");

AWS.config.update({
    apiVersion: '2012-08-10',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // // accessKeyId default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // accessKeyId: "9oiaf7",
    // // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // secretAccessKey: "yz5i9"
});

var ddb = new AWS.DynamoDB();

(async function () {
    console.log("Start script!");

    var params = {
        TableName: 'TestTableMischianti',
    };

    try {
        const data = await ddb.deleteTable(params).promise();
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response
    }catch (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred

        console.log('message --> ', err.message);
    }

    console.log("End script!");

})();

Se provi a lanciare di nuovo l’eliminazione ottieni un errore su console come questo

Start script!
Full error response {
  "message": "Requested resource not found: Table: TestTableMischianti not found",
  "code": "ResourceNotFoundException",
  "time": "2021-01-15T08:48:55.825Z",
  "requestId": "NTOVJQRJ2SMS5T58H17ND0SA2JVV4KQNSO5AEMVJF66Q9ASUAAJG",
  "statusCode": 400,
  "retryable": false,
  "retryDelay": 6.585825073089313
}
message -->  Requested resource not found: Table: TestTableMischianti not found
End script!

Ottenere l’elenco delle tabelle

SDK v2

Penso che tu abbia capito come funzionano questi scripts, ora aggiungerò lo script asincrono e sincrono senza commenti dettagliati.

Qui lo script asincrono.

/*
 * DynamoDB Script Examples async await
 * Get list of tables from
 * DB of selected region in AWS.config.update
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 *
 */

var AWS = require("aws-sdk");

AWS.config.update({
    apiVersion: '2012-08-10',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // // accessKeyId default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // accessKeyId: "9oiaf7",
    // // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // secretAccessKey: "yz5i9"
});

var docClient = new AWS.DynamoDB();

console.log("Start script!");

var params = {
    // ExclusiveStartTableName: 'SmartHomeEsp8266', // optional (for pagination, returned as LastEvaluatedTableName)
};
docClient.listTables(params, function(err, data) {
    if (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred

        console.log('message --> ', err.message);
    } else {
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response

        console.log('--------------- TABLES ---------------')
        data.TableNames.forEach((elem, idx) => console.log(idx, elem));
    }
});
console.log("End script!");

Niente di nuovo, devi solo prestare attenzione all’attributo TableNames dove vengono inseriti i dati.

Start script!
End script!
Full success response {
  "TableNames": [
    "EsempioSmartHome",
    "SmartHomeEsp8266",
    "TabellaSkillEsterna",
    "TestTableMischianti",
    "TestTableMischianti4"
  ]
}
--------------- TABLES ---------------
0 'EsempioSmartHome'
1 'SmartHomeEsp8266'
2 'TabellaSkillEsterna'
3 'TestTableMischianti'
4 'TestTableMischianti4'

Qui lo script sincrono.

/*
 * DynamoDB Script Examples async await
 * Get list of tables from
 * DB of selected region in AWS.config.update
 *
 * AUTHOR:  Renzo Mischianti
 *
 * https://mischianti.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2017 Renzo Mischianti www.mischianti.org All right reserved.
 *
 * You may copy, alter and reuse this code in any way you like, but please leave
 * reference to www.mischianti.org in your comments if you redistribute this code.
 */

var AWS = require("aws-sdk");

AWS.config.update({
    apiVersion: '2012-08-10',
    region: "eu-west-1",
    // endpoint: "http://localhost:8000",
    // // accessKeyId default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // accessKeyId: "9oiaf7",
    // // secretAccessKey default can be used while using the downloadable version of DynamoDB.
    // // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead.
    // secretAccessKey: "yz5i9"
});

var ddb = new AWS.DynamoDB();

(async function () {
    console.log("Start script!");

    var params = {
        // ExclusiveStartTableName: 'SmartHomeEsp8266', // optional (for pagination, returned as LastEvaluatedTableName)
    };

    try {
        const data = await ddb.listTables(params).promise();
        console.log('Full success response', JSON.stringify(data,null,2)); // successful response

        console.log('--------------- TABLES ---------------')
        data.TableNames.forEach((elem, idx) => console.log(idx, elem));
    }catch (err) {
        console.log('Full error response', JSON.stringify(err,null,2)); // an error occurred

        console.log('message --> ', err.message);
    }

    console.log("End script!");

})();

Un altro tipo di gestione

Naturalmente puoi cambiare, modificare o ricavare tutte le informazioni direttamente sulla console AWS nella sezione DynamoDB

https://eu-west-1.console.aws.amazon.com/dynamodb/home?region=eu-west-1

DynamoDB Tabella creata
DynamoDB Tabella creata

o tramite aws cli, ma la sintassi diventa piuttosto noiosa, ecco il comando per la precedente generazione di tabella:

aws dynamodb create-table --table-name TestTableMischianti --attribute-definitions AttributeName=ItemId,AttributeType=S AttributeName=ItemName,AttributeType=S --key-schema AttributeName=ItemId,KeyType=HASH AttributeName=ItemName,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1

non è così complesso ma molto difficile da leggere.

Grazie

  1. DynamoDB JavaScript SDK v2 v3: prerequisiti ed introduzione
  2. DynamoDB JavaScript SDK v2 v3: gestione delle tabelle
  3. DynamoDB JavaScript SDK v2 v3: aggiungere elementi con DB o DocumentClient
  4. DynamoDB JavaScript SDK v2 v3: gestione degli elementi
  5. DynamoDB JavaScript SDK v2 v3: scansionare i dati delle tabelle e paginazione
  6. DynamoDB JavaScript SDK v2 v3: query

Spread the love

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *