DynamoDB delete table complete status - amazon-web-services

I am deleting a table in DynamoDB using the following Javascript in Node.
var params = {
TableName : "MyTable"
};
dynamodb.deleteTable(params, function(err, data) {
// Not really done yet...!
});
I need to know when the table has actually been deleted. The callback doesn't indicate this, as it is still in the deleting process when this is called. Is there a way to know when the delete has completed?

The waitFor API can be used to check for the non-existence of table.
Waits for the tableNotExists state by periodically calling the
underlying DynamoDB.describeTable() operation every 20 seconds (at
most 25 times).
Sample code to delete the table and check for the non-existence of table using waitFor API:-
var AWS = require("aws-sdk");
AWS.config.update({
region : "us-west-2",
endpoint : "http://localhost:8000"
});
var dynamodb = new AWS.DynamoDB();
var params = {
TableName : "country"
};
var paramsWaitFor = {
TableName : 'country' /* required */
};
function waitForTableNotExists() {
dynamodb.waitFor('tableNotExists', paramsWaitFor, function(waitForErr,
waitForData) {
if (waitForErr) {
console.log(waitForErr, waitForErr.stack); // an error occurred
} else {
console.log('Deleted ====>', JSON.stringify(waitForData, null, 2));
}
});
}
dynamodb.deleteTable(params, function(err, data) {
if (err) {
console.error("Unable to delete table. Error JSON:", JSON.stringify(
err, null, 2));
} else {
console.log("Deleted table. Table description JSON:", JSON.stringify(
data, null, 2));
waitForTableNotExists();
}
});

Related

Lambda not deleting DynamoDB records when triggered with Cloud Watch events

I am trying to delete items in my Dynamodb table using Cloud Watch event triggered Lambda. This lambda scans the dynamo table and deletes all expired items. My code seems to be working when I test it using the test event in the console (i.e it deletes all the expired items). But when lambda gets triggered automatically using the Cloud Watch event it does not delete, event though I see that the lambda is being triggered.
exports.handler = async function () {
var params = {
TableName: TABLE_NAME
}
try {
const data = await docClient.scan(params).promise();
const items = data.Items;
if (items.length != 0) {
Promise.all(items.map(async (item) => {
const expirationDT = new Date(item.ExpiresAt);
const now = new Date();
if (now > expirationDT) {
console.log("Deleting item with otc: " + item.Otc + " and name: " + item.SecretName);
const deleteParams = {
TableName: TABLE_NAME,
Key: {
"Otc": item.Otc,
"SecretName": item.SecretName,
},
};
try {
await docClient.delete(deleteParams).promise();
} catch (err) {
console.log("The Secret was not deleted due to: ", err.message);
}
}
}))
}
} catch (err) {
console.log("The items were not able to be scanned due to : ", err.message)
}}
I know using DynamoDB TTL is an option, but I need these deletions to be somewhat precise, and TTL can sometimes take up to 48 hours, and I am aware I can use a filter when retrieving records to counter-act that. Just wondering what's wrong with my code here.
You need to await Promise.all or your lambda will end execution before it resolves
await Promise.all(items.map(async (item) => {
const expirationDT = new Date(item.ExpiresAt);
const now = new Date();
// ...

lambda function returning null for deleting item in DynamoDB

hi Ive been trying to get my lambda function to delete an item in dynamo db but the function is simply returning null and i have no idea how to even start debugging it, hoping someone here has the knowledge to help
my table has guid as its primary partition key and username as its sort key
heres my code in .js
const AWS = require("aws-sdk");
// Initialising the DynamoDB SDK
const documentClient = new AWS.DynamoDB.DocumentClient();
exports.handler = async (event) => {
const { guid, username } = event
const params = {
TableName: "Items", // The name of your DynamoDB table
Key:{
"guid": {"S" : guid},
"username": {"S" : username}
}
};
try {
// Utilising the scan method to get all items in the table
documentClient.delete(params, function(err, data) {
if (err) {
return("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
return("DeleteItem succeeded:", JSON.stringify(data, null, 2));
}
});
}
catch (e) {
return {
statusCode: 500,
body: e
};
}
};
this is the payload for the test event im using in lambda
{
"guid": "34",
"username": "newusername"
}
You are using async function handler. So your function probably just finishes before your code actually has a chance to execute.
You can overcome this issue by wrapping your code around new Promise as shown in the docs

how to define attribute types in Dynamodb?

I want to store data attributes are threadId , threadType (sms, livechat ,fb) , createat and updateat how I define the threadType I follow this procedure but output displays all of the types of threadType?
and how to fix the time? this is manual input is there any method to get system time?
var doClient = new AWS.DynamoDB.DocumentClient();
var DynamoDB = new AWS.DynamoDB({});
var table = "thread";
var threadId = "3";
var threadType = "livechat";
var createDate = "11:38";
var updateDate = "12:00";
var channelName = "three";
var params = {
TableName : table,
Item:
{
"threadId" : threadId,
"threadType" : { "SS": ["sms", "livechat" ,"fb"] },
"createDate" : { 'S' : createDate },
"updateDate" : { 'S' : updateDate },
"channelName" :{'S' : channelName }
}
};
console.log("Adding a new item...");
doClient.put(params, function(err, data) {
if (err) {
console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("Added item:", JSON.stringify(data, null, 2));
}
});
I need that only livechat display in a result of threadtype because in this insertion I need livechat
It looks like you are modelling threadType as a StringSet, which means that it can contain multiple values. If you just want to store 'livechat' then just store this value as a String. DynamoDB doesn't have the concept of server side validation, or support for Enums, though some SDK's do - in node.js there is no Enum type. As for the system time, there is no way to ask for DynamoDB to insert the system time for you. Most people will insert epoch seconds or milliseconds as a Number type for sorting purposes, and based on the client's timestamp, which should use NTP and when hosted within EC2 will be super super close to the DDB fleet timestamp.

AWS DynamoDB DocumentClient not throwing expected error

I'm using DynamoDB to store data and trying to read items using JavaScript. I have a function that will read an item from a specified table, but I want to detect when an item doesn't exist in the table:
function getChapterLocations() {
var table = bibleSelect.value.replace(/\s/g, '');
var chapter = bookSelect.value + " " + chapterSelect.value;
var params = {
TableName: table,
Key:{
"chapter": chapter
}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.get(params, function(err, data) {
if (err) {
currentLocations = {};
} else {
currentLocations = data.Item.locations;
}
getText();
});
}
The problem is, even when an item doesn't exist in the table, err is always null. When an item doesn't exist, all I get is an error that looks something like this in the console:
callListeners https://sdk.amazonaws.com/js/aws-sdk-2.164.0.min.js:48:1027
emit https://sdk.amazonaws.com/js/aws-sdk-2.164.0.min.js:48:695 emitEvent
https://sdk.amazonaws.com/js/aws-sdk-2.164.0.min.js:47:18756
I would just ignore this error, but when an item doesn't exist, it prevents getText() from being called.

Adding a where clause to AWS DynamoDB

I am trying to create a getItem request in AWS Lambda to access DynamoDB like so:
dynamodb.getItem({
TableName: "DataTable",
Key: {
user: {
S: user
},
deleted: {
BOOL: false
}
}
}, function(err, data) {
if (err) return fn(err);
else {
if ('Item' in data) {
fn(null, user);
} else {
fn(null, null); // User not found
}
}
});
It worked fine when I passed the user in as that was the primary key on the table. I added a deleted boolean to create a soft delete on users. But one I added that in the schema errors started to happen as deleted isn't part of the primary key. I want a way to add it as a where clause coming from the relational DB world. How is this done? Thanks. :o)
The getItem cannot be used if the data has to be filtered by any non-key attributes.
I think in the above case, the 'deleted'attribute is a non-key attribute. So, the Query API should be used to filter the data along with key attribute.
Please refer the FilterExpression in the below example.
FilterExpression : 'deleted = :createdate'
(AWS.Request) query(params = {}, callback)
Sample code:-
var params = {
TableName : table,
KeyConditionExpression : 'yearkey = :hkey and title = :rkey',
FilterExpression : 'deleted = :deleted',
ExpressionAttributeValues : {
':hkey' : year_val,
':rkey' : title,
':deleted' : {BOOL : false}
}
};
docClient.query(params, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err,
null, 2));
} else {
console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
}
});
For your use case, the key, filter condition and expression attribute value should be as mentioned below:-
KeyConditionExpression : 'user = :user',
FilterExpression : 'deleted = :deleted',
ExpressionAttributeValues : {
':user' : 'John',
':deleted' : {BOOL : false}
}