DynamoDB - Delete item - The provided key element does not match the schema - node.js

I've gone through many answers on stack overflow for similar questions. But the problem is a bit different here. I know that I should be sending the key to delete the operation (pk or pk/sk). But in my case, I only have one key in schema (verified by describe-table)
{ .....
"TableName": "**********",
"KeySchema": [
{
"AttributeName": "user_id",
"KeyType": "HASH"
}
],
....}
The table has been create using following sam code
DynamoDbTable:
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
- AttributeName: "user_id"
AttributeType: "S"
KeySchema:
- AttributeName: "user_id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
SSESpecification:
SSEEnabled: True
TableName: !Ref TableName
Here are the params that I'm creating for the delete call
var docClient = new AWS.DynamoDB.DocumentClient({
apiVersion: '2012-08-10',
region: process.env.AWS_REGION
});
const deleteParams = {
TableName: process.env.TABLE_NAME,
Key: {
user_id: connectionData.Items[0].user_id
}
};
try {
let response = await docClient.delete(deleteParams).promise();
console.log('deleted');
} catch (err) {
return {
statusCode: 500,
body: 'Failed to disconnect: ' + JSON.stringify(err)
};
}
Any help will be much appreciated

Related

DynamoDB - how to read a record by primary key values?

I'm trying to get an item from a DynamoDB table, but this error "ValidationException: The provided key element does not match the schema" keeps happening.
These are the parameters i created the table:
TableName : "Users-test",
KeySchema: [
{ AttributeName: "id", KeyType: "HASH"}, //Partition key
{ AttributeName: "email", KeyType: "RANGE" } //Sort key
],
AttributeDefinitions: [
{ AttributeName: "id", AttributeType: "S" },
{ AttributeName: "email", AttributeType: "S" }
]
And i'm trying to access the data like this:
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: 'Users-test',
Key:{
id: "someID",
email: "example#example.com"
}
};
docClient.get(params, function...
I know the record exists on the database and i can filter by id using the aws console, but actually using code i cannot get a record using the primary key, i tried to remove the "email" field from params variable, but it returned the same error.
You can this,
const config = {
region: 'eu-central-1'
};
const docClient = new AWS.DynamoDB.DocumentClient(config);
const params = {
TableName: 'Users-test',
Key:{
"someId",
"example#example.com"
}
};
docClient.get(params, function...
Also, you can make your function async
const docClient = new AWS.DynamoDB.DocumentClient(config);
const params = {
TableName: 'Users-test',
Key:{
"someId",
"example#example.com"
}
};
const result = await docClient.get(params).promise();

DynamoDB: Can not update the dynamoDB item in node js

I am new in dynamoDB, I am trying to update and get item to db but i can't, always getting "The provided key element does not match the schema"
this my serverless.yml code for dynamoDB
resources:
Resources:
TodosDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
-
AttributeName: in_organization_id
AttributeType: S
-
AttributeName: sp_customer_id
AttributeType: S
-
AttributeName: qb_customer_id
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
-
AttributeName: in_organization_id
KeyType: RANGE
-
AttributeName: sp_customer_id
KeyType: RANGE
-
AttributeName: qb_customer_id
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: 'insightly'
and this is my update method
/* Update Record in DB */
this.UpdateDB = (event) => {
return new Promise(async (resolve, reject) => {
try {
const data = event;
const params = {
TableName: process.env.TABLE_NAME,
Key: {
in_organization_id : data.in_organization_id
},
UpdateExpression: "set qb_customer_id = :qb_customer_id",
ExpressionAttributeValues:{
":qb_customer_id":data.qb_customer_id
},
ReturnValues:"UPDATED_NEW"}
const response=await dynamoDb.update(params).promise();
resolve(response);
} catch (err) {
reject(err.message);
}
});
};
like wise i have getmethod to get item
/* Get/Check Org ID from DB */
this.checkOrgID = (OrgID) => {
return new Promise(async (resolve, reject) => {
try {
const params = {
TableName: process.env.TABLE_NAME,
Key: {in_organization_id :OrgID}
};
const response = await dynamoDb.get(params).promise();
resolve(response);
} catch (err) {
reject(err.message);
}
});
};
but it always giving me error. Please help me to find out the solution. Thanks in Advance.
if you are using the AWS SDK for Javascript you can use the information bellow:
const document = {
document_id: "1",
name: "John",
lastname: "Snow"
}
where document_id is my key
return dynamodb
.put({ TableName: 'tableName', Item: document })
.promise();

How to insert to DynamoDb just if the key does not exist

I want to add id + some values to a DynamoDb just once. If the id exists already it should do nothing or update
I can go with
search
if not found > insert
if found > do nothing or update (for now do nothing is fine)
But hopfully there is a better way to do it. The id should be the key to check for.
That's the code in node:
const dynamodbParams = {
TableName: process.env.DYNAMODB_TABLE_BLICKANALYTICS,
Item: {
id: userId,
createdAt: timestamp
},
};
dynamoDb.put(dynamodbParams).promise()
.then(data => {
console.log('saved: ', dynamodbParams);
})
.catch(err => {
console.error(err);
});
I use this in yml. Don't know if there are options to set this up in yml
resources:
Resources:
DynamoDbTableExpenses:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
-
AttributeName: createdAt
AttributeType: N
KeySchema:
-
AttributeName: id
KeyType: HASH
-
AttributeName: createdAt
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE_BLICKANALYTICS}
You can do the whole thing with a single UpdateItem operation:
const dynamodbParams = {
TableName: process.env.DYNAMODB_TABLE_BLICKANALYTICS,
Key: {id: userId},
UpdateExpression: 'SET createdAt = if_not_exists(createdAt, :ca)',
ExpressionAttributeValues: {
':ca': {'S': timestamp}
}
};
dynamoDb.updateItem(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
console.log(data);
}
}
If you only want to do insert if not exists, you can easily do that with PutItem:
const dynamodbParams = {
TableName: process.env.DYNAMODB_TABLE_BLICKANALYTICS,
Item: {
id: userId,
createdAt: timestamp
},
ConditionExpression: 'attribute_not_exists(id)'
};
dynamodb.putItem(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} else {
console.log(data);
}
}
You can come up with more complex ways how to set or update attributes in an item by combining the condition expressions and update expressions.
Note I have not fully tested the code, so please comment if there's any error, but it should work.

Date range query not works in dynamodb

I am new to aws dynamodb and hit the query as shown below
let params = {
TableName: tableName
};
if (from && to) {
params.FilterExpression = 'createdOn >= :from and createdOn <= :to';
params.ExpressionAttributeValues = { ":from": from, ":to": to }
}
return new Promise((resolve, reject) => {
docClient.scan(params, (err, data) => {
if (err) {
//do stuff
}else{//do stuff}
});
});
and here is my db schema
const ApplicationDataSchema = {
TableName: "data1", //config.get('aws_tables.APPLICATIONS_DATA'),
KeySchema: [
{ AttributeName: "id", KeyType: "HASH" },
{ AttributeName: 'createdOn', KeyType: 'RANGE' }
],
AttributeDefinitions: [
{ AttributeName: "id", AttributeType: "S" },
{ AttributeName: 'createdOn', AttributeType: 'N' }
],
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 10
}
}
is there any need to change in schema I am not getting the correct result.
createdOn field contains epoc time eg:"1548659664131"
If you want to use a filter expression with 2 dates, you're probably looking for the BETWEEN statement.
'#createdOn between :from and :to'
I suggest that you take a look at this guide on AWS for using dynamodb with javascript.

Serverless: dynamodb delete where condition

I am trying, and failing, to delete a record with a condition. I keep getting this error: The provided key element does not match the schema.
This is my definition in the yml:
resources:
Resources:
vuelosTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Delete
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
-
AttributeName: vuelta
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
-
AttributeName: vuelta
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}
These are the params when trying to delete:
params = {
RequestItems: {
[process.env.DYNAMODB_TABLE]: [{
DeleteRequest: {
Key: {
"vuelta": "2017-09-09"
}
}
}]
}
};
I know it's something I am not getting, but I don't know what. Any ideas?
Your table key is both id and vuelta but you're only providing vuelta in the delete request. Modify the key in your delete request so it contains both the id and vuelta.
Also, depending on your client library may need to specify
Key: {
id: { S: "some value" },
vuelta: { S: "some value" }
}

Resources