The provided key element does not match the schema - updateItem - amazon-dynamodb

var params = {
ExpressionAttributeNames: {
"#AT": "date"
},
ExpressionAttributeValues: {
":t": {
BOOL: false
}
},
Key: {
"#AT": {
N: data.Items[i].date.N
},
"accountid": {
S: data.Items[i].accountid.S
}
},
ReturnValues: "ALL_NEW",
TableName: "tab",
UpdateExpression: "SET #AT = :t"
}
db.updateItem(params, function (err, data) {
if (err) console.log(err);
else {
//console.log(data);
}
});
What is happening is that the code is not working. It gives me this error:
message: 'The provided key element does not match the schema'
This is what is in table details:
Primary partition key - date (Number)
Primary sort key -

The problem is that you've got a composite key (date + accountid) in your params, but your table is only configured with a partition key.
Either use this:
var params = {
ExpressionAttributeValues: {
":t": { BOOL: false }
},
ExpressionAttributeNames: {
"#at": "isRelevant",
},
Key: {
"date": { N: data.Items[i].date.N }
},
ReturnValues: "ALL_NEW",
TableName: "tab",
UpdateExpression: "SET #at = :t"
}
db.updateItem(params, function (err, data) {
if (err) {
console.log(err);
} else {
//console.log(data);
}
});
Or, if you expected to use accountid as a sort key, then you'll need to rebuild your table.

Related

Why is dynamodb.update() is not updating the field in my Table?

I have a dynamodb Table named "user_subscription", I want to update the status field from "ACTIVE" to "INACTIVE",
const params = {
TableName: "user_subscription",
Key: {
userId: userId,
subscription_id: "abc",
},
updateExpression: "SET status = :newStatus",
expressionAttributeValues: { ":newStatus": "INACTIVE" },
ReturnValues: "ALL_NEW",
};
console.log("params", params);
try {
dynamoDb.update(params, (error, data) => {
console.log("error", error, "data", data);
});
} catch (err) {}
This code doesn't update the status field.
The response data which I get is:
Attributes: {
plan_id: 'dkdkkd',
subscription_id: 'abc',
userId: 'ebef4c92-9fa8-4e1b-878f-d5753bb4042a',
updatedAt: '2022-12-25T08:18:32.681Z',
status: 'ACTIVE',
createdAt: '2022-12-25T08:18:32.681Z'
}
Status is a reserved keyword in DynamoDB, I believe the code you shared should be throwing several errors, are you sure you are executing the correct code while testing?
To fix your errors, try these params:
const params = {
TableName: "user_subscription",
Key: {
userId: userId,
subscription_id: "abc",
},
UpdateExpression: "SET #status = :newStatus",
ExpressionAttributeValues: { ":newStatus": "INACTIVE" },
ExpressionAttributeNamee: { "#status": "status" },
ReturnValues: "ALL_NEW",
};

Add a number to a list item with DynamoDB

This is the DynamoDB table structure I'm working on:
{
"userId": "99999999-9999-9999-9999-999999999999",
"userProfile": {
"email": "myemail#gmail.com",
"firstName": "1234124",
"lastName": "123423",
},
"masterCards": [
{
"cardId": 101000000000001,
"cardImage": "logo.png",
"cardName": "VipCard1",
"cardWallet": "0xFDB17d12057b6Fe8c8c425D2DB88d8475674567"
},
{
"cardId": 102000000000002,
"cardImage": "logo.png",
"cardName": "VipCard2",
"cardWallet": "0xFDB17d12057b6Fe8c8c425D2DB88d8183454345"
},
{
"cardId": 103000000000003,
"cardImage": "logo.png",
"cardName": "VipCard3",
"cardWallet": "0xFDB17d12057b6Fe8c8c425D2DB88d8184345345"
}
],
}
I'm trying to increase the cardId field by one for the first list item with this Lambda function:
const dynamoDB = new AWS.DynamoDB({region: 'eu-central-1', apiVersion:'2012-08-10'});
const counterId="99999999-9999-9999-9999-999999999999"
const params = {
TableName:"FidelityCardsUsers",
Key: {"userId":{"S":counterId}},
UpdateExpression:"ADD #masterCards[0].#cardId :increment",
ExpressionAttributeNames:{
"#masterCards": "masterCards",
"#cardId": "cardId"
},
ExpressionAttributeValues:{":increment": {"N": "1"}}
}
dynamoDB.updateItem(params, function(err, data) {
if (err) {
console.log('error getting counter from DynamDB: ',err)
callback(err);
} else {
callback(null,data)
}
})
In return I get only a new top-level attribute named "mastercards[0].cardId[0]" with a value number set to 1.
I have tried to increment In an array and its work fine with AWS.DynamoDB.DocumentClient()
Example :
var AWS = require("aws-sdk");
var docClient = new AWS.DynamoDB.DocumentClient();
let params = {
TableName:'tableName',
Key: {
'venueId': 'VENUE_002'
},
UpdateExpression: "ADD #walk.#coordinates[0] :increment",
ExpressionAttributeNames: {
'#walk': 'walk',
'#coordinates': 'coordinates'
},
ExpressionAttributeValues: {
':increment': 1 // This is from the client
},
ReturnValues: 'UPDATED_NEW'
};
docClient.update(params, function (err, data) {
if (err) {
console.log('failure:updateShuttleDirection:failed');
console.log(err);
} else {
console.log('success:updateShuttleDirection:complete');
console.log(data);
}
});
Sample Data:
"walk": {
"coordinates": [
10,
20
],
"type": "Point"
},
I have tried to increment 10 to 11 and its work fine
Reading the doc here, it seems that:
the ADD action can only be used on top-level attributes, not nested
attributes.

Best way to add a new key-value pair in an item of items list in DynamoDB

I have a sample Table info as -
items: [{
"key1":"value1",
"key2":"value2"
}
]
I have to update this like below -
items: [{
"key1":"value1",
"key2":"value2",
"key3": [{"subkey1":"value1"}, {"subkey2:"value2"}]
}
]
You can use Update API with SET operator.
In the below example, categoryList has the key3 value mentioned in OP.
Sample Code:-
var docClient = new AWS.DynamoDB.DocumentClient();
var categoryList = [{"subkey1":"value1"}, {"subkey2" : "value2"}];
var params = {
TableName : "Movies",
Key : {
"yearkey" : 2016,
"title" : "The Big New Movie 1"
},
UpdateExpression : "set #category = :categoryList",
ExpressionAttributeNames: {
'#category' : 'category'
},
ExpressionAttributeValues: {':categoryList' : categoryList},
ReturnValues: 'UPDATED_NEW'
};
console.log("Updating the item...");
docClient.update(params, 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));
}
});

How to create and populate lists in DynamoDB

I wish to create an Item in DynamoDB that is a list. This is my code:
var list_update_params = {
TableName: "table01",
Key: {
"MachineID": {
"S": MachineID
},
"Hour": {
"S": Hour
}
},
UpdateExpression: "set var01_list = list_append(var01_list, :ot)",
ExpressionAttributeValues: {
":ot": {"L": [{"N": var01}]}
},
ReturnValues: "NONE"
};
dynamodb.updateItem(list_update_params, function(err, data) {
if (err) console.log(err, err.stack);
else console.log("Updated List to DynamoDB");
});
The problem is list_append expects the attribute var01_list to already be present, but I wouldn't know at the first insert. Is there a technique where it'll let me create an insert a List attribute if one doesn't exist and append to it in later calls?
Got the answer from a similar post here.
UpdateExpression: "set var01_list= list_append(if_not_exists(var01_list, :empty_list), :h)",
ExpressionAttributeValues: {
":h": {"L": [{"N":var01}]},
":empty_list": {"L": []}
},
The key was using if_not_exists with list_append. Didn't know that could be done in this matter

Error in updating item in dynamodb

I have created simple table (username, password), the key is username.
the table contains one item:
{
"username" : "someuser",
"password" : "cat"
}
Now, i want to update from "cat" to "dog"
dynamodb.updateItem({
TableName: "users",
Key: { "username": { "S" : "someuser" } },
UpdateExpression : "SET password =:pass",
ExpressionAttributeValues : { ":pass" : { "S" : "dog" } }
}, function(err, data) {
if (err)
console.log(JSON.stringify(err, null, 2));
else
console.log(JSON.stringify(data, null, 2));
});
But i got error:
{
"message": "Invalid attribute value type",
"code": "ValidationException",
"time": "2015-11-14T20:22:36.381Z",
"statusCode": 400,
"retryable": false
}
Finally i have found that dynamodb javascript shell is not identical to dynamodb running on AWS.
The error above not occur on real dynamodb.
EDIT:
for example, the following works:
var params = {
TableName: config.SCRIPTTABLE,
Key: { id : { S: script.id }},
UpdateExpression: "SET title = :title, description = :desc, code = :code, tags = :tags, pub = :pub",
ExpressionAttributeValues: {
":title": { S: script.title },
":desc" : { S: script.description },
":code" : { S: script.code },
":tags" : { SS: script.tags },
":pub" : { BOOL: script.pub }
},
ReturnValues: "ALL_NEW"
};
dynamodb.updateItem(params, function(err, data) {
if (err) {
console.log(JSON.stringify(err));
context.fail('INTERNAL_SERVER_ERROR');
} else {
context.succeed();
}
});

Resources