I have a JSON having an array of objects in the following format. How can i add it in dynamoDB using a lambda function(NodeJS). Assume my JSON is in an s3 bucket name "databucket" and the file name is data.json. I have used "userId" as the key while creating the DB table. Thanks in advance
{
"records": [
{
"first-name": "Mark",
"last-name": "rob",
"userId": "fvdvfd"
},
{
"first-name": "Alan",
"last-name": "thomas",
"userId": "wee"
},
{
"first-name": "Joan",
"last-name": "Young",
"userId": "wee"
}
]
}
First, you have to retrieve the data.json from S3 bucket and read it's content into a variable.
Secondly, you should create dynamodb parameter to provide to the dynamodb client PUT method. Since it is an array of objects you have to loop through the array and put each object or else you can use batchWrite method in dynamodb as follows,
var AWS = require('aws-sdk');
var insertBatchRecords = function(callback) {
var dynamodb = new AWS.DynamoDB();
var bulkInsertParams = {
RequestItems: {
"Records": [
{
PutRequest: {
Item: {
"first-name": "Mark",
"last-name": "rob",
"userId": "fvdvfd"
}
}},
{
PutRequest: {
Item: {
"first-name": "Alan",
"last-name": "thomas",
"userId": "wee"
}
}}]
}
};
dynamodb.batchWriteItem(bulkInsertParams, callback);
}
Related
I want to scan dynamodb using filter on product_id showing in below json of table.
Can anybody explain how to do scanning using filter of product_id.
Wants to scan dynamodb table data using documentclient.
Wants to find all fields which has product_id: something
{
"mandi_id": 1,
"product": [
{
"updated_price": 24,
"product_id": 2,
"last_price": 23
},
{
"updated_price": 24,
"product_id": 5,
"last_price": 23
}
],
"status": "active",
"createdAt": "2022-04-21T08:23:41.774Z",
"mandiCloseTime": "4pm",
"mandi_description": "anaj mandi",
"mandi_name": "gaziabad anaj mandi",
"state": "uttar pradesh",
"city": "gaziabad",
"main_image_s3": "",
"mandi_latlong": {
"lng": 77.48325609999999,
"lat": 28.680346
},
"mandiOpenTime": "10am",
"updatedAt": "2022-04-21T08:23:41.774Z",
"address_name": "gavindpuram",
"landmark_name": "mandi",
"village": "gaziabad",
"postal": "201013"
}
I have tried the following set of code but it is returning empty array list
var params = {
TableName: "dev-agrowave-mandi-management",
// Select: "ALL_ATTRIBUTES"
FilterExpression: "contains(#product,:product)",
ExpressionAttributeNames: {
"#product": "product",
},
ExpressionAttributeValues: { ":product": {"product_id":parseInt(id)}
}
};
let lastEvaluatedKey = 'dummy'; // string must not be empty
const itemsAll = [];
while (lastEvaluatedKey) {
const data = await docClient.scan(params).promise();
itemsAll.push(...data.Items);
lastEvaluatedKey = data.LastEvaluatedKey;
if (lastEvaluatedKey) {
params['ExclusiveStartKey'] = lastEvaluatedKey;
}
}
return {msg:itemsAll,params:params};
I'm trying to store the json object in dynamodb using the code given below.
exports.handler = function (event, context, callback) {
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "Logs";
id_val = 1
var params = {
TableName: table,
Item: {
"id": id_val,
"message": event
}
};
docClient.put(params, function(err, data) {
if (err) {
callback(null, JSON.stringify(err, null, 2));
context.fail("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
}
});
}
Input to event
[
{
"id": 1,
"demographic": {
"firstName": "John",
"middleName": "w",
"lastName": "Doe",
"suffix": "jr",
"birthDate": "1990-02-02",
"gender": "M",
"ssn": 123
}
}
]
What's stored in the table
{
"id": {
"N": "84.20420287568176"
},
"message": {
"L": [
{
"M": {
"demographic": {
"M": {
"birthDate": {
"S": "1990-02-02"
...
...
...
Why is datatype being stored in the table? How can one break this down so that attributes are stored separately?
That's the way dynamoDB stores data because when we look at the data we should be able to know the datatype of the field, which is excatly same as data type of column in relationa data base. Though data stores and displays like this in dynamoDB when we get data from dynamoDB through an actual application or API we can get rid of data types, which will return the actual data only.
I Am running a lambda function (NodeJS) to upload some documents to AWS Cloud Search. I keep getting the following error.
{
"errorMessage": "{ [\"The value of tags cannot be a JSON array or object\"] }",
"errorType": "DocumentServiceException",
"stackTrace": [
"Object.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:48:27)",
"Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/rest_json.js:37:8)",
"Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)",
"Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)",
"Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:678:14)",
"Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)",
"AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)",
"/var/task/node_modules/aws-sdk/lib/state_machine.js:26:10",
"Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:38:9)",
"Request.<anonymous> (/var/task/node_modules/aws-sdk/lib/request.js:680:12)"
]
}
I have followed the document format of
var item = {
type: 'add',
id: key,
fields: {
userid: value.userId,
storyid: value.storyId,
description: value.description,
title: value.title,
type: 'xyz'
}
}
This is the code I am using to upload the data
exports.handle = function(e, ctx, cb) {
ctx.callbackWaitsForEmptyEventLoop = false;
var documentsBatch = e.data;
var params = {
contentType: 'application/json',
documents: JSON.stringify(documentsBatch)
};
var req = cloudsearchdomain.uploadDocuments(params, function(err, data) {
if (err){
// an error occurred
cb(err, null);
}else{
// successful response
}
});
req.send();
}
My stringified data when logged looks something similar to
[
{
"type": "add",
"id": "FpgAxxxxKrM4utxosPy23--KhO6FgvxK",
"fields": {
"userid": "FpgARscKlxaxutxosPy23",
"storyid": "-KhxbPpRP7REEK",
"description": "xyz 🔥 🔥",
"title": "umm",
"type": "story"
}
},
{
"type": "add",
"id": "FccccxosPy23--KiYbrrPjtJVk2bghO-W",
"fields": {
"userid": "FpgARfPy23",
"storyid": "-KiYbrfggO-W",
"description": "noo",
"title": "lalaa out",
"type": "story"
}
}
]
Can someone point me in the right direction?
The problem was with another JSON object which had an additional JSON attribute other than fields. Once I was able to find and remove it everything worked. There should be a lint-er for the same, or the SDK should throw a better exception.
Below is a sample item object/record stored in DynamoDb. I use NodeJS and AWS.DynamoDB.DocumentClient to access the database.
I'm building out a PUT function to update the status for an JSON object in an array. The function will have access to the Item's uuid and room's uuid. How can I simply (creatively) update the value of corresponding status field, given the array of JSON objects?
Params:
let params = {
TableName: room-table,
Key: {
uuid: event.body.uuid
},
UpdateExpression : "??",
ExpressionAttributeNames: {
"??":"??"
},
ExpressionAttributeValues:{
"??":"??"
},
ReturnValues:"ALL_NEW"
};
Item Object:
{
"Item": {
"uuid": "77b1e88e-5e60-44d9-b6ca-aec345c0dc99",
"rooms": [
{
"room": "303",
"status": "pending",
"uuid": "b8f1c1a8-04a9-4c2e-82ad-bc3e81face35"
},
{
"room": "302",
"status": "pending",
"uuid": "42fdc61a-4a25-4316-90c9-60209875d208"
},
{
"room": "678",
"status": "pending",
"uuid": "7bedc115-20ed-4c3e-9cd7-7fed0520f4df"
}
],
"status": "pending"
}
}
It's not possible to do this with ExpressionAttributeValues. I had to build a function to modify the object, similar to below:
function setStatus(jsonObj, uuid, newStatus) {
for (var i=0; i<jsonObj.length; i++) {
if (jsonObj[i].uuid === uuid) {
jsonObj[i].status = newStatus;
return jsonObj;
}
}
}
let params = {
TableName: room-table,
Key: {
uuid: event.body.uuid
},
UpdateExpression : "SET #stat = :stat",
ExpressionAttributeNames: {
"#stat": "status"
},
ExpressionAttributeValues:{
":stat": "updatedStatusValue"
},
ReturnValues:"ALL_NEW"
};
ExpressionAttributeNames is needed because status is a DynamoDB reserved word. More info on Attribute Name and Attribute Value placeholders is available in the DynamoDB docs.
I'm trying to set up a small api from AWS Lambda to DynamoDB and I am having trouble figuring out if and how I can write an array of objects into a key.
I have an object like
{
"teamName": "Team Awesome",
"members": [
{
"email": "person-1#example.com",
"name": "Bob"
},
{
"email": "person-2#example.com",
"name": "Alice"
}
]
}
The members array is giving me issues, in the docs it looks like it can be done considering the list types, but there is just no example how HOW to do it, and I am running out of ways to try it.
So is it possible to write something in this format at all and how do you in that case do it?
Example code - what do I put at ???
var AWS = require('aws-sdk');
var dynamodb = new AWS.DynamoDB();
exports.handler = function(event, context) {
var tableName = "GDCCompetition";
var datetime = new Date().getTime().toString();
DynamoDB.putItem({
"TableName": tableName,
"Item": {
"datetime": {
"N": datetime
},
"teamName": {
"S": event.teamName
},
"members": ???
}
});
}
The documentation is not really obvious, but there is a thing called DocClient, you can pass a usual JS object to it and it will do all the parsing and transformation into AWS object (with all the types). You can use it like this:
var AWS = require("aws-sdk");
var DynamoDB = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "MyTable",
Item: {
"teamName": "Team Awesome",
"members": [
{
"email": "person-1#example.com",
"name": "Bob"
},
{
"email": "person-2#example.com",
"name": "Alice"
}
]
}
};
DynamoDB.put(params, function (err) {
if (err) {
return throw err;
}
//this is put
});
You could convert the object to DynamoDb record first
const AWS = require('aws-sdk');
var tableName = "GDCCompetition";
var datetime = new Date().getTime().toString();
const members = [
{
"email": "person-1#example.com",
"name": "Bob"
},
{
"email": "person-2#example.com",
"name": "Alice"
}
];
const marshalled = AWS.DynamoDB.Converter.marshall({ members });
const params = {
"TableName": tableName,
"Item": {
"datetime": {
"N": datetime
},
"teamName": {
"S": event.teamName
},
"members": marshalled.members,
},
}
AWS.DynamoDB.putItem(params, function (err) {
if (err) {
return throw err;
}
});