Get criteria not match the schema - node.js

Im trying to get an Item from DynamoDB based on Primary Key but it throws me an exception:
ValidationException: The provided key element does not match the schema
Here is how my table looks:
I'm following a tutorial and here is how I wrote my get:
let params = {
TableName: process.env.CALL_NAVEGATION_HISTORY_TABLE,
Key: {
"Id": requestBody.CallSid
}
}
dynamoDb.get(params, function(err, data) {
if(err){
console.log('Error on dynamodb', err);
callback(null, Helpers.xmlTwimlResponse(twiml));
}
console.log(data);
callback(null, Helpers.xmlTwimlResponse(twiml));
});
What is wrong on my code?

Sometimes the most obvious thing is what we miss right in front of our eyes.
let params = {
TableName: process.env.CALL_NAVEGATION_HISTORY_TABLE,
Key: {
"Id": requestBody.CallSid
}
}
The Key name is case-sensitive. If you change it to 'id' it should work fine.

Related

DynamoDB - Delete Item based on ConditionExpression on Sort Key

Is it possible to delete records from dynamodb based on PrimaryKey and ConditionExpression on SortKey?
Following code sample is throwing an exception for me
DeleteVideoCall = async function (pk, sk) {
let params = {
TableName: this._tableName,
Key: {
pk: { S: pk.toString() },
sk: { S: sk.toString() }
},
ConditionExpression: "begins_with(sk,:sk)",
ExpressionAttributeValues: {
":sk" : { S: sk.toString() + "_" }
}
};
return this._ddb
.deleteItem(params)
.promise()
.then((data) => {
console.log(`Video Call '${pk}/${sk}' deleted`);
return null;
})
.catch((error) => {
console.error(
`Error deleting video room '${pk}/${sk}' (${error})`
);
throw error;
});
};
I want to delete all records that begins_with sk and . For example if sk is 560622 then delete all records where sk begins_with 560622
with the code above I get this error:
Error deleting video room '10900/560622'
(ConditionalCheckFailedException: The conditional request failed)
You can't do that. You need whole key to perform a delete. What you can do:
query items (limit retrieved properties to your PK and SK)
use batch-write to remove multiple items, it also accepts delete requests

Query using only partition key in DynamoDB

I am trying to query on my table using only the partition key and ignoring the sort key but I get no items.
My global secondary index looks like this:
And my table looks like this:
And this is my query:
const params = {
ExpressionAttributeValues: {
':app': 'app',
},
IndexName: 'glc-development-gsi1',
KeyConditionExpression: 'sk = :app',
TableName: this.tableName,
};
return new Promise((resolve, reject) => {
this.client.query(params, (err, data) => {
console.log(data);
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
According to all the documentation I've read and the other questions on here, this should work and I can't understand why it doesn't. The scan from my index is also empty.
Finally found my solution. DynamoDB stores data in indexes only when both the partition key and the sort key are defined, so my index was empty all the time. The query was fine.

CouchDB/Cloudant query view by key that is array?

alice.view('characters', 'soldiers', {
'keys': ['Hearts', 'Clubs']
}, function(err, body) {
if (!err) {
body.rows.forEach(function(doc) {
console.log(doc.value);
});
}
});
Does this filter on key: "Heart" or key: "Clubs" or the exact match key: ["Hearts", "Clubs"]? I wish to do the latter where my keys are arrays with 2 items.
Also if I JUST inserted into the db, can I expect this view to immediately be up to date when I run that code?
the view() function above will filter on key: "Heart" or key: "Clubs".
instead, you may want to try using the startkey and endkey:
*DB_NAME*/_design/characters/_view/soldiers?startkey=["Hearts", "Clubs"]&endkey=["Hearts", "Clubs"]&inclusive_end=true
something, like this:
alice.view('characters', 'soldiers', {
'startkey': ['Hearts', 'Clubs'],
'endkey': ['Hearts', 'Clubs'],
'inclusive_end': true
}, function(err, body) {
if (!err) {
body.rows.forEach(function(doc) {
console.log(doc.value);
});
}
})
reference:
https://stackoverflow.com/a/42398481

How to overwrite an item with a different schema but same key in DynamoDB using nodejs on lambda

I am trying to overwrite an item in DynamoDB (that uses a primary key called username) by using put as shown below:
console.log('writing commands',existingCommands,message.username);
var t2 = performance();
var writeParams = {
Item: {
username: message.username,
commands: existingCommands // Sorry for the confusing name, due to deepExtend existingCommands are the new commands
},
TableName: TableName
};
docClient.put(writeParams, function(err, data){
if(err){
console.error('error',err);
} else {
console.log('write result',data);
var t3 = performance();
console.info('delete & write performance',(t3-t2).toFixed(3));
}
// End function
context.done();
});
That works for:
Inserting a new item where the username doesn't exist.
Updating an item that matches the schema of the Item i'm trying to insert, for example, I'm trying to insert that item:
{
"username":"ausin441062133",
"commands": {
"command1":"command",
"command2":"command"
}
}
and if there's an item that matches the schema and the username it'll get overwritten, i.e.
{
"username":"ausin441062133",
"commands": {
"command1":"I will be overwritten",
"command2":"I will be overwritten"
}
}
But when there's an item with the exact username but different schema, it doesn't work, i.e.
{
"username":"ausin441062133",
"commands": {
"command1":"I will NOT be overwritten"
}
}
What command do I need to use to overwrite an existing item if it matches the username?
Eventually as Dmitry suggested update works but it needs some different params as opposed to put here's my code:
// Step 3 write command back
console.log('writing commands',existingCommands,message.username);
var t2 = performance();
var updateParams = {
Key: {
username: message.username
},
UpdateExpression: "set commands = :c",
ExpressionAttributeValues: {
":c":existingCommands
},
ReturnValues: "UPDATED_NEW",
TableName: TableName
};
docClient.update(updateParams, function(err, data){
if(err){
console.error('error',err);
} else {
console.log('write result',data);
var t3 = performance();
console.info('delete & write performance',(t3-t2).toFixed(3));
}
// End function
context.done();
});

DynamoDB scanning using filter

Im new to DynamoDB and have a table which is "feeds" and partition key is "id" and i have 3 other attributes which are "category", "description", "pubDate".
I want to query the "category" attribute. But it doesn't work, because i can only query the partition key (hashkey), if im right.
Now my query is that which doesnt work;
let category = event.category;
const params = {
Key: {
"category": {
S: category
}
},
TableName: "feeds"
};
dynamodb.getItem(params, function (err, data) {
if (err) {
console.log(err);
callback(err);
}
else {
console.log(data);
callback(null, data);
}
});
How can i make it work? I tried to write a scan query but i couldn't understand the documentation of AWS good.
Edit: I did make it work with the help of Dunedan. Here is the working code,
var params = {
TableName: 'feeds',
IndexName: 'category-index',
KeyConditionExpression: 'category = :category',
ExpressionAttributeValues: {
':category': 'backup',
}
};
var docClient = new AWS.DynamoDB.DocumentClient();
docClient.query(params, function(err, data) {
if (err) callback(err);
else callback(null, data);
});
If your application will regularly query for the category, you should check out Global Secondary Indexes (GSI), which allow you to generate a projection of your data with another key than the original hash key as the key you can use to query.
Scanning and filtering as you suggested doesn't scale very well, as it fetches all data in the table and just filters the results.

Resources