Can anyone provide an example of a dynamodb document client upsert? - node.js

I'm looking for a non trivial upsert example in node for AWS dynamodb's DocumentClient. Can someone share a sample that has worked for them?
I would like to see an example that sets a created_at, updated_at and a id field on creating the record but only sets the updated_at when the record is found and updated.

This should achieve your goal. My apologies, as I missed your criteria in my original posting. I am assuming id is the key in your table.
'use strict';
var AWS = require('aws-sdk');
var ec2 = new AWS.EC2({ apiVersion: '2016-09-15' });
var ddb = new AWS.DynamoDB.DocumentClient();
AWS.config.region = 'us-east-1';
var ret = {};
const ddbTbl = 'table_name';
var date = new Date();
var dateAsIso = date.toISOString();
exports.handler = (event, context, callback) => {
var key = 'bar';
var params = {
TableName: ddbTbl,
Key: {
"id": key
},
UpdateExpression: "set #u = :t, #c = if_not_exists(#c, :t)",
ExpressionAttributeNames: {
"#u": "updated_at",
"#c": "created_at"
},
ExpressionAttributeValues: {
":t": dateAsIso
},
ReturnValues: "UPDATED_NEW"
};
ddb.update(params, function(err, data) {
if (err) {
console.log(err, err.stack);
ret.ddbUpdate = err;
callback(null, {success: false, message: ["ddb upsert failed"], payload: ret});
// or use the regular callback for failures if you don't want to do your own envelope response
} else {
console.log(data);
ret.ddbUpdate = data;
callback(null, {success: true, message: ["ddb upsert succeeded"], payload: ret});
}
});
};

Related

DynamoDB Scan with Lambda not returning elements

I have a Lambda with the following code:
// Load the AWS SDK for Node.js.
var AWS = require("aws-sdk");
// Set the AWS Region.
AWS.config.update({ region: "us-east-2" });
exports.handler = function(event, context, callback) {
// Create DynamoDB service object.
var ddb = new AWS.DynamoDB({ apiVersion: "2012-08-10" });
var params = {
TableName: "Ranking",
ProjectionExpression: "#username, Score, Duration",
FilterExpression: "#username = :username",
ExpressionAttributeNames: {
"#username": "Username",
},
ExpressionAttributeValues: {
":username": {
S: 'Alberto'
},
}
};
let toReturn = [];
ddb.scan(params, function (err, data) {
if (err) {
toReturn = err
} else {
toReturn = data.Items;
}
});
let response = {
statusCode: 200,
body: JSON.stringify(toReturn)
};
callback(null, response)
};
However I always see [] as response...
My current DB has the following records:
So my question is... why I don't get back that item?
Since you are using callbacks, your code should be as below. Also Duration is reserved keyword, so it also needs to be modified as below:
// Load the AWS SDK for Node.js.
var AWS = require("aws-sdk");
// Set the AWS Region.
AWS.config.update({ region: "us-east-2" });
exports.handler = function(event, context, callback) {
// Create DynamoDB service object.
var ddb = new AWS.DynamoDB({ apiVersion: "2012-08-10" });
var params = {
TableName: "Ranking",
FilterExpression: "#username = :username",
ProjectionExpression: "#username, Score, #duration",
ExpressionAttributeNames: {
"#username": "Username",
"#duration": "Duration",
},
ExpressionAttributeValues: {
":username": {
S: 'Alberto'
},
}
};
ddb.scan(params, function (err, data) {
if (err) {
callback(null, err)
} else {
callback(null, data.Items)
}
});
};

AWS Lambda function written in nodejs is not updating my DynamoDB

I'm a student who is new to AWS, but I have reached a blocker....
I am trying to use a lambda function to update an attribute for an item in my dynamodb table. The lambda function is being triggered, but for some reason I am unable to update the item.
I was able to successfully delete the item from the dynamodb, but when I try to update an attribute for an item nothing happens.
The attribute human_confirmed is not updating to true after the function executes. I've been trying different things I've found on Google, but nothing is working :(
console.log('Loading function');
var AWS = require('aws-sdk');
exports.handler = (event, context, callback) => {
AWS.config.update({
region: "us-east-1"
});
var dynamodb = new AWS.DynamoDB.DocumentClient();
var instance = event.instanceID;
var InstanceName = instance;
var params = {
TableName: "reminders",
Key: {
"instanceID": {
S: InstanceName
},
},
UpdateExpression: 'SET #a = :x',
ExpressionAttributeNames: {'#a' : 'human_confirmed'},
ExpressionAttributeValues: {
':x' : 'true',
},
ReturnValues:"UPDATED_NEW"
};
dynamodb.update(params, function(err, data) {
if (err)
callback(err, null); // an error occurred
else
callback(null, data); // successful response
});
callback(null, "Updating resource from reminder table: " + InstanceName + ".... The system will no longer contain automated emails about this resource's tags!");
};
make sure you have this configuration: dynamodb:PutItem in your serverless.yml file
iamRoleStatements:
- Effect: "Allow"
Action:
- "dynamodb:PutItem"
Resource: "*"
Thanks for the help #kaxi1993
I believe my IAMRole permissions were correct. Here was the code that worked for me.
'use strict';
console.log('Loading function');
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
exports.handler = (event, context, callback) => {
AWS.config.update({
region: 'us-east-1'
});
var instance = event.instanceID;
var params = {
TableName: 'reminders',
Key: {
'instanceID': {
S: instance
}
},
UpdateExpression: 'set human_confirmed = :x',
ExpressionAttributeValues: {
':x': {S: 'true'},
},
ReturnValues: 'UPDATED_NEW'
};
dynamodb.updateItem(params, function(err, data) {
if (err)
callback(err, null); // an error occurred
else
callback(null, data); // successful response
});
callback(null, 'Updating instance from reminder table: ' + instance + '.... The system will no longer contain automated emails about this resource.');
};

node.js module answer undefined [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
Can someone give me a hand? I tried to figure it out but i ran out of ideas.
-------------dynamo.js....
module.exports.readUser = function (user_id) {
AWS.config = new AWS.Config();
AWS.config.update({region: "eu-west-1"});
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "user";
var user_id = user_id;
var params = {
TableName: table,
Key:{
"user_id": user_id
}
};
docClient.get(params, function(err, data) {
if (err) {
return err;
} else {
//console.log(data); <-- data is filled
return data;
}
});
var dynamo = require("./dynamo.js");
console.log(dynamo.readUser(4711998));
The data you log out inside the function is only the returned value for the anonymous function given to docClient.get as the second argument. The exported readUser function has no return statement and therefore it is undefined.
Because of the async nature of javascript you have to access the result via a callback like so:
module.exports.readUser = function (user_id, cb) {
...
docClient.get(params, function(err, data) {
if (err) {
return err;
} else {
return cb(data);
}
});
}
var dynamo = require("./dynamo.js");
dynamo.readUser(4711998, function (user) {
console.log(user);
});
docClient.get is an asynchronous function. You need promisify this function or use callback.
Use callback:
module.exports.readUser = function (user_id, cb) {
AWS.config = new AWS.Config();
AWS.config.update({ region: "eu-west-1" });
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "user";
var user_id = user_id;
var params = {
TableName: table,
Key: {
"user_id": user_id
}
};
docClient.get(params, cb);
}
var dynamo = require("./dynamo.js");
dynamo.readUser(4711998, function (err, user) {
if(err)
console.error(err);
else
console.log(user);
});
Use promise:
module.exports.readUser = function (user_id) {
AWS.config = new AWS.Config();
AWS.config.update({ region: "eu-west-1" });
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "user";
var user_id = user_id;
var params = {
TableName: table,
Key: {
"user_id": user_id
}
};
return new Promise(function(resolve, reject) {
docClient.get(params, function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
var dynamo = require("./dynamo.js");
dynamo.readUser(4711998).then(function (user) {
console.log(user);
}).catch(function(err) {
console.error(err);
});
Read more:
How do I promisify the AWS JavaScript SDK?
https://aws.amazon.com/ru/blogs/developer/support-for-promises-in-the-sdk/

Return only attribute value from an query expression

Hi I need to return only the value of attribute from the code below
console.log('starting function');
var AWS = require('aws-sdk');
/*var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});*/
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
var newResponse =
exports.handler = (event, context, abcd) => {
var queryParameters = {
TableName: 'Ignition1',
KeyConditionExpression : 'GROUP_EDGE_ID = :Test',
ExpressionAttributeValues: {
":Test":'Group-EdgeNode'
},
Limit : 1,
ScanIndexForward: false, // Returns the item with the Highest Primary Sort
Key in this case the TIMESTAMP
/*FilterExpression: TempTag,*/
ProjectionExpression: "TempTag",
//Select: "SPECIFIC_ATTRIBUTES",
};
docClient.query(queryParameters, function(err, data){
if(err){
abcd(err, null);
}else{
abcd(null, data.Items);
}
How ever the result I get is
"TempTag": 60
I need to return only the attribute value of 60 as string. But am not sure how to get to that stage.

Getting null value when trying to query value which is not present in dynamo db using node.js

I am new to dynamoDB and node.js I have written a code where it will make a query to the database (dynamodb) and look for an element which is entered by the user in the database. I am able to verify that but when the user tries with some other number which is not present in the database I am getting a null value.
My table name is "DevReferenceNumber" and only one column which is primary key "referencenumber".
'use strict';
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient({ region : 'us-east-1'});
function close(sessionAttributes, fulfillmentState, message) {
return {
sessionAttributes,
dialogAction: {
type: 'Close',
fulfillmentState,
message,
},
};
}
exports.handler = (event, context, callback) => {
try{
console.log(`event.bot.name=${event.bot.name}`);
if(event.bot.name != 'getCustomerReferenceNumber'){
callback('Invalid Bot Name');
}
dispatch(event, (response) => {
callback(null, response)
});
}catch(err){
callback("Error is occured while querying");
}
};
function dispatch(intentRequest, callback){
console.log(`dispatch UserID => ${intentRequest.userId}, intentName => ${intentRequest.currentIntent.name}`);
const intentName = intentRequest.currentIntent.name;
if(intentName === "checkReferenceNumber"){
return referenceNumber(intentRequest, callback);
}
}
function referenceNumber(intentRequest, callback){
const enteredReferenceNumber = intentRequest.currentIntent.slots.ReferenceNumber;
const sessionAttributes = intentRequest.sessionAttributes;
console.log("User has entered reference number is --> " + enteredReferenceNumber);
var params = {
TableName : "DevReferenceNumber",
KeyConditionExpression: "#refer = :ref",
ProjectionExpression : "#refer",
ExpressionAttributeNames: {
"#refer" : "referencenumber"
},
ExpressionAttributeValues:{
":ref": parseInt(enteredReferenceNumber)
}
};
docClient.query(params, function(err, data){
if(err){
callback(close(sessionAttributes, 'Fulfilled', {
contentType: 'PlainText',
content : 'Developer reference number is not matched with data from database'}));
}
else {
data.Items.forEach(function (item){
console.log("User matched data is ==> " + item.referencenumber);
callback(close(sessionAttributes, 'Fulfilled', {
contentType: 'PlainText',
content : 'Developer reference number is matched with data from database'}));
});
}
});
}
It is obvious that you will get a null record when you don't have a matching record. If you don't want null from node callback then you can do a custom logic to do a null check and return data according to the way you want.

Resources