With using the API version of '2012-08-10', I'm trying to create a table on DynamoDB. My Lambda code acquiring groupID
via API. Once the table is created, as a follow up I'm trying to add the first item to the table as follows:
const AWS = require('aws-sdk');
AWS.config.update({ region: 'eu-central-1' });
const dynamodb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
exports.handler = (event, context, callback) => {
var itemParams = {
...some itemParams
});
var tableParams = {
...some tableParams
};
dynamodb.createTable(tableParams, function (err, data) {
if (err) { console.log(err, err.stack) }
else { console.log("Table created", data); }
});
dynamodb.putItem(itemParams, function (err, data) {
if (err) callback(null, err);
else callback(null, data);
});
};
Unfortunately I'm receiving a "ResourceNotFoundException" error. Basically putItem doesn't recognize the table just created. Any suggestions on how to create a trigger here? Is there a way to putItem to the table that is just created? Thank you!
Also in case you are wondering the details of params:
var tableParams = {
AttributeDefinitions: [
{
AttributeName: "memberID",
AttributeType: "S"
}
],
KeySchema: [
{
AttributeName: "memberID",
KeyType: "HASH"
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 2,
WriteCapacityUnits: 2
},
TableName: "plexiGr_" event.groupID
};
var itemParams = {
TableName: "plexiGr_" event.groupID,
Item: {
"memberID": { S: event.groupAdmin },
"memberName": { S: "Julius" },
"memberAge": { N: "32" }
},
ConditionExpression: "attribute_not_exists(groupID)"
};
CodePudding user response:
You are not waiting until your table is created. The commands for creating the table and putting an item in it are run in sequence but without waiting for the callbacks.
So either you put the code to write the item into the callback of the create table action or you use promises to wait until the table is created.
dynamodb.createTable(tableParams, function(err, data) {
if (err) {
console.log(err, err.stack);
return;
}
dynamodb.putItem(itemParams, function(putItemErr, putItemData) {
if (putItemErr) callback(null, putItemErr);
else callback(null, putItemData);
});
});
Using promises:
await dynamodb.createTable(tableParams).promise();
await dynamodb.putItem(itemParams).promise();
CodePudding user response:
The DynamoDB CreateTable
operation is asynchronous - it just starts to create a table, but returns before the table's creation is finished. The CreateTable document explains that:
CreateTable
is an asynchronous operation. Upon receiving aCreateTable
request, DynamoDB immediately returns a response with aTableStatus
ofCREATING
. After the table is created, DynamoDB sets theTableStatus
toACTIVE
. You can perform read and write operations only on an ACTIVE table.
In other words, when CreateTable
completes, the table is not yet usable: You now need to do a loop of DescribeTable
, waiting until the table's status has become ACTIVE
. Only then you can use the table.
Because this is a useful loop, most AWS libraries have a function to automate it. I'm familar with the Python one in the boto3 library, but I assume nodejs also has a similar one. Or you can just call DescribeTable
yourself.
To reiterate, despite what other responses said, it is not enough to wait for CreateTable
to complete. It will complete much earlier than you can really use the table. You must also wait, separately, for the new table's status to change to ACTIVE
.