How do you count as like mysql "select count(*) from tablename" , in DynamoDB using the dynamoose node module?
There is no direct equivalent available in DynamoDB. However, one workaround would be to get the ItemCount using describe table API.
Drawback of ItemCount:-
DynamoDB updates this value approximately every six hours. Recent
changes might not be reflected in this value.
Code to get item count of Movies table from local DynamoDB instance:-
'use strict';
var dynamoose = require('dynamoose');
dynamoose.AWS.config.update({
accessKeyId : 'AKID',
secretAccessKey : 'SECRET',
region : 'us-east-1'
});
dynamoose.local();
var Schema = dynamoose.Schema;
var Table = dynamoose.Table;
var table = new Table('Movies', null, null, dynamoose);
table.describe(function(err, data) {
if (err) {
console.log(JSON.stringify(err));
} else {
console.log(JSON.stringify(data, null, 2));
console.log("Number of item =====>", JSON.stringify(data.Table.ItemCount, null, 2));
}
});
Output:-
Number of item =====> 24
Related
I am quite new to work with DynamoDB. I would like to query DynamoDB database for a specific column value and get the data that matches that specific column value using NodeJS sdk
In this case, the DynamoDB is already deployed.
Please suggest how to implement this workflow using Node JS.
most important thing is to create a JSON object containing
the parameters needed to query the table, which in this example includes the table name, the
ExpressionAttributeValues needed by the query, a KeyConditionExpression that uses those
values to define which items the query returns, and the names of attribute values to return for each
item. Call the query method of the DynamoDB service object.
here is an example to query dynamodb with nodejs sdk
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'REGION'});
// Create DynamoDB service object
var b = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var params = {
ExpressionAttributeValues: {
':s': {N: '2'},
':e' : {N: '09'},
':topic' : {S: 'PHRASE'}
},
KeyConditionExpression: 'Season = :s and Episode > :e',
ProjectionExpression: 'Episode, Title, Subtitle',
FilterExpression: 'contains (Subtitle, :topic)',
TableName: 'EPISODES_TABLE'
};
b.query(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
data.Items.forEach(function(element, index, array) {
console.log(element.Title.S + " (" + element.Subtitle.S + ")");
});
}
});
I am trying to create a silent auction site. My Lambda function should update an item under the condition that the submitted bid > current high bid. However, the condition does not seem to be applying; the update occurs even if the submitted bid is less than the current high bid.
Please help me identify what I'm doing wrong:
##My DynamoDB table looks like this:##
Table name: SilentAuction2
Primary partition key: ItemID (String)
other attributes:
CurrentHighBid (Number)
HighestBidder (String)
Notes (String)
BidHistoryBids (List)
BidHistoryPPL (List)
My condition, as stated above, is that the incoming event.NewBid is greater than the CurrentHighBid. Here is the Lambda code in Node.JS:
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
exports.handler = function index(event, context, callback) {
var table = "SilentAuction2";
var ItemID = event.ItemID;
var NewBid = event.NewBid;
var NewBidder = event.NewBidder;
var Notes = event.Notes;
var params = {
TableName:table,
Key:{
"ItemID": ItemID
},
//update and append values
UpdateExpression: "SET #BidList = list_append(#BidList, :hb),
#PplList = list_append(#PplList, :hp),
CurrentHighBid =:c,
HighestBidder=:h,
Notes=:n",
//condition on which to update if true
ConditionalExpression: " :c > CurrentHighBid",
ExpressionAttributeNames: {
"#BidList" : "BidHistoryBids",
"#PplList" : "BidHistoryPPL"
},
ExpressionAttributeValues:{
":hb":[NewBid],
":hp":[NewBidder],
":n":Notes,
":c":NewBid,
":h":NewBidder
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, function(err, data){
if(err){
callback(err, null);
}else{
callback(null, data);
}
});
};
This links were helpful in researching ConditionalExpression within DynamoDB:
https://egkatzioura.com/2016/08/09/update-dynamodb-items-with-node-js/
http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.NodeJs.03.html#GettingStarted.NodeJs.03.05
I am facing some issue with querying data from DynamoDB can any one of you help me on this? I am coding in NodeJS.
My table looks like below with,
Primary key: RequestId
Secondary index: Userid with sortkey Timestamp
When I am pulling the data using UserId, I am getting lot's for records so, planning to pull the data with Timestamp condition.
RequestId Request Timestamp UserId
var doc = require("dynamodb-doc");
var dynamo = new doc.DynamoDB();
var userid_col = "amzn1.ask.account.AGCAPY7JBHQWHTNGAHJJ";
var databaserec = { TableName: "dna_cdknow_prod_historylog",
IndexName: "UserId-TimeStamp-index",
KeyConditionExpression: "UserId = :input",
FilterExpression : 'created between :val1 and :val2',
ExpressionAttributeValues:{ ":input": userid_col, ":val1" : "2016-05-23T00:00:00Z", ":val2" : "2017-05-23T16:20:49Z" } };
The below code should work if the GSI definition is as follows:-
UserId - Partition key of GSI
created - Sort key of GSI
Corrected code:-
var databaserec = {
TableName: "dna_cdknow_prod_historylog",
IndexName: "UserId-TimeStamp-index",
KeyConditionExpression: "UserId = :input AND created between :val1 and :val2'",
ExpressionAttributeValues:{ ":input": userid_col, ":val1" : "2016-05-23T00:00:00Z", ":val2" : "2017-05-23T16:20:49Z" }
};
docClient.query(databaserec, function(err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log(params);
console.log("Query succeeded.");
data.Items.forEach(function(item) {
console.log("Item :" + JSON.stringify(item));
});
}
});
i am working on node js using dynamoDB with dynamoose. For example, let us assume we have a table Employees in which there is two attributes Branch and Domain. I have a given branch and domain, now i want to get all the employees under either the given branch or the give domain. Can anyone please give an example for above case?
Here is the code to query and scan.
The code connects to DynamoDB local instance.
Employee Schema used:-
Branch - Hash Key
No sort key in the table
Domain - is the attribute
Code:-
var dynamoose = require('dynamoose');
dynamoose.AWS.config.update({
accessKeyId : 'AKID',
secretAccessKey : 'SECRET',
region : 'us-east-1'
});
dynamoose.local();
var Schema = dynamoose.Schema;
var Table = dynamoose.Table;
var Employee = dynamoose.model('employee', { branch: String, domain: String });
Employee.get('UK').then(function (data) {
console.log('Get :' + JSON.stringify(data));
});
Employee.query('branch').eq('UK').exec(function (err, data) {
console.log('Query :' + JSON.stringify(data));
});
Employee.scan('domain').eq('Banking').exec(function (err, data) {
console.log('Scan :' + JSON.stringify(data));
});
Explanation:-
Employee.get(..) - Get the data by hash key
Employee.query (..) - Get the data by hash key along with other attributes as needed
Employee.scan (..) - Get the data based on non-key attributes
I need to update my dynamo db table by using only partition key. But i got validation exeption.
I have created a table with 3 fields.
id (Partition Key)
name (Sort Key)
age
Then i have triyed to update age field using only id.(tryied to modify age 30 to 40) this is my code
var AWS = require("aws-sdk");
AWS.config.update({
region: "us-east-1",
});
var params = {
TableName: 'test',
Key: { id: '100' },
UpdateExpression: 'set #age = :age ',
ConditionExpression: '#age = :testAge',
ExpressionAttributeNames: { '#age': 'age' },
ExpressionAttributeValues: { ':age': '40', ':testAge': '30' }
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.update(params, function (err, data) {
if (err) {
console.log(err);
}
else {
console.log(data);
}
});
But i got error like this.
{ [ValidationException: The provided key element does not match the schema]
message: 'The provided key element does not match the schema',
code: 'ValidationException',
time: Thu Nov 17 2016 22:38:01 GMT+0530 (IST),
requestId: '34PNMFM6CEACQIRHTSV77OI0JRVV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 0 }
After getting error, i modified my params variable like this
var params = {
TableName: 'test',
Key: { id: '100',name: 'manaf' },
UpdateExpression: 'set #age = :age ',
ConditionExpression: '#age = :testAge',
ExpressionAttributeNames: { '#age': 'age' },
ExpressionAttributeValues: { ':age': '40', ':testAge': '30' }
};
Using this, updation is successfully completed. How to update table using without sort key?
Currently, the DynamoDB update API doesn't have an option to update the item by partition key only. There is no batchUpdateItem API similar to batchWriteItem as well.
So, if the sort key is not available, get all the sort keys of partition key and update each item for the partition and sort key combination.
For the primary key, you must provide all of the attributes. For
example, with a simple primary key, you only need to provide a value
for the partition key. For a composite primary key, you must provide
values for both the partition key and the sort key.
Sample code:-
You may need to change it for your table. The below code uses "Movies" table which has "yearkey" as partition key and "title" as sort key.
The below code updates the "createdate" attribute for the given hash key "2012".
The variable paramsUpdate is formed based on the query operation. Please update it accordingly for your requirement (i.e. table structure). Logic remains same, you just need to change the table name and key values accordingly.
var AWS = require("aws-sdk");
var creds = new AWS.Credentials('akid', 'secret', 'session');
AWS.config.update({
region : "us-west-2",
endpoint : "http://localhost:8000",
credentials : creds
});
var docClient = new AWS.DynamoDB.DocumentClient();
var hashKey = 2012;
var paramsQuery = {
TableName : "Movies",
KeyConditionExpression : 'yearkey = :hkey',
ExpressionAttributeValues : {
':hkey' : hashKey
}
};
function updateItem(paramsUpdate) {
console.log("Updating the item...");
docClient.update(paramsUpdate, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(
err, null, 2));
} else {
console.log("UpdateItem succeeded:", JSON.stringify(data));
}
});
}
docClient.query(paramsQuery, function(err, data) {
if (err) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err,
null, 2));
} else {
console.log(data.Count);
var itemIndex = 0;
while (itemIndex < data.Count) {
console.log('Hashkey to be updated ======>',
data.Items[itemIndex].yearkey,
';Title to be updated ========>',
data.Items[itemIndex].title);
var paramsUpdate = {
TableName : "Movies",
Key : {
"yearkey" : data.Items[itemIndex].yearkey,
"title" : data.Items[itemIndex].title
},
UpdateExpression : "set #createdate = :createdate",
ExpressionAttributeNames : {
'#createdate' : 'createdate'
},
ExpressionAttributeValues : {
':createdate' : '2016-11-17'
},
ReturnValues : 'UPDATED_NEW'
};
updateItem(paramsUpdate);
itemIndex++;
}
}
});
In DynamoDB, partition key + sort key is treated as a "composite primary key", which uniquely identifies an item (on the contrary, Dynamo also supports simple primary key, which only contains partition key). So you need both to update an item. This is the reason that you can have two items with the same partition key but different sort key. So if you only provide the partition keys, Dynamo will get confused with which item to update.
For your current table configuration, the only way to update an item given a partition key is to make a query with only partition key to get all the items, and filter out the one with the intended sort key. Then use the combination of partition key and sort key to update this item.