Site icon Renzo Mischianti

DynamoDB JavaScript SDK v2 v3: manage tables – 2

Spread the love

In this article we are going to execute and analyze the code downloaded from previous article, we are going to create, delete and get the list of tables.

DynamoDB JavaScript SDK v2 and v3 manage tables

All sdk from AWS are available via npm in nodejs repository, so when you execute npm i on the folder with package.json you obtain all source code that is needed to execute the scripts in the github reposotory.

Create a simple table

You can create a table directly from console at (change region with your):

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

Then click with create table

you must add the table name and a partition key, we are going to add a sort key also.

SDK v2

The default method to query the DynamoDB is to use asychronous calls, but you can use the promise() to use async, await method, so the request become synchronous.

The promises are also used to execute in parallel a series of command.

First we are going to do simple creation with callback function, pay attention to set the correct region in the script.

As you can see we are going to import the whole aws-sdk package, than use It to execute all the commands.

The create command is createTable and the first parameter is the information needed for the table creation, the second is the callback function.

/*
 * 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!");

This table have 2 key:

but we are going to see the pratical difference when we see the examples of queries.

To execute this script go in the folder dynamodb-examples\jsv2 and launch node table_create.js

The console result of the script is

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"
  }
}

You can see that Start script! and End script! are executed immediately, then arrive the response, this because the callback execution is asynchronous, so first all the code was executed, then when the REST call answered the callback was called.

A better solution (the default in v3) is to use async, await, with this method the code stop until a response is given.

To execute this script go in the folder dynamodb-examples\jsv2 and launch 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!");

})();

I surround all the code with the async function, and put the await on the createTable promise, and the result in console is now

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!

Now Start script! is at the beginning and End script! is at the end, so the execution was synchronous.

SDK v3

The new version of SDK use synchronous call as default method for execution, but you can use asynchronous as well but discouraged, we will look at all v3 call types when we see the element add method.

Set the correct region of your account.

To execute this script go in the folder dynamodb-examples\jsv3 and launch 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 this script the single command are separated to grant modular import

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

You can also call these commands in a single step with DynamoDB instance, you can call db.createTable but is discouraged because you must import all packages and you lost modularization features.

The console result become.

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!

You can check Start script! and End script! to verify that the script is synchronous.

Verify on AWS console.

DynamoDB Table created

You can verify the creation of the table in the DynamoDB AWS console at the link (pay attention to the region, set the correct one)

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

If you clink on table in the list you can get more informations.

Delete table

The deletion script is quite simple, for v2 I’m going to show sync and async version. Pay attention to the region.

SDK v2

Here the async version script, you can execute with node table_create.js on v2 folder

/*
 * 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!");

For all script the only parameter needed is TableName, here the console result.

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"
  }
}

Now the sync version (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!");

})();

If you try to launch the delete again you obtain an error on console like this

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!

Get the table list

SDK v2

I think that you understand how working this scripts, now I’m going to add the async and sync script without verbose comment.

Here the async script.

/*
 * 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!");

Nothing new, you must only pay attention to the attribute TableNames where the data is placed.

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

Here the sync script.

/*
 * 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!");

})();

Another type of management

Naturally you can change, modify or query all the information directly on AWS console in the DynamoDB section

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

DynamoDB Table created

or via aws cli, but the syntax become quite tedious, here the command for the previous table generation:

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

it isn’t so complex but very difficult to read.

Thanks

  1. DynamoDB JavaScript SDK v2 v3: prerequisite and SDK v2 v3 introduction
  2. DynamoDB JavaScript SDK v2 v3: manage tables
  3. DynamoDB JavaScript SDK v2 v3: add items with DB or DocumentClient
  4. DynamoDB JavaScript SDK v2 v3: manage items
  5. DynamoDB JavaScript SDK v2 v3: scan table data and pagination
  6. DynamoDB JavaScript SDK v2 v3: query


Spread the love
Exit mobile version