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.
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:
ItemId
ant It’s a partition key, this type of keys are mandatory in query and you can used it to create a group of data to query or as a simple primary key;ItemName
It’s similar to an index key used to get specified data in partition.
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.
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
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
- DynamoDB JavaScript SDK v2 v3: prerequisite and SDK v2 v3 introduction
- DynamoDB JavaScript SDK v2 v3: manage tables
- DynamoDB JavaScript SDK v2 v3: add items with DB or DocumentClient
- DynamoDB JavaScript SDK v2 v3: manage items
- DynamoDB JavaScript SDK v2 v3: scan table data and pagination
- DynamoDB JavaScript SDK v2 v3: query