Home > Blockchain >  createTable first, then putItem into table that just created
createTable first, then putItem into table that just created

Time:04-04

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 a CreateTable request, DynamoDB immediately returns a response with a TableStatus of CREATING. After the table is created, DynamoDB sets the TableStatus to ACTIVE. 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.

  • Related