Serverless: dynamodb delete where condition - node.js

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" }
}

Related

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

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

DynamoDB BatchGet always gives "The provided key element does not match the schema"

So I was stuck for a while now with dynamo db's batchGet operation.
Here is my table definition (in serverless)
Resources:
MyTable:
Type: AWS::DynamoDB::Table
DeletionPolicy: Retain
Properties:
TableName: MyTable
TimeToLiveSpecification:
AttributeName: ttl
Enabled: true
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: myId
AttributeType: S
- AttributeName: otherId
AttributeType: S
KeySchema:
- AttributeName: myId
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: otherIdIndex
KeySchema:
- AttributeName: myId
KeyType: HASH
- AttributeName: otherId
KeyType: RANGE
Projection:
ProjectionType: ALL
here is how I do batchGet in my function.
await getClient().batchGet({
RequestItems: {
'MyTable': {
Keys: [
{'myId': { 'S': 'z12345' }},
{'myId': { 'S': 'z12346' }},
],
ProjectionExpression: 'myId, otherId',
},
},
}).promise();
however, for some reason, I only get an exception The provided key element does not match the schema Did I missed something?
Thanks in advance!
Edit
Searching deeper, I stumbled upon this answer from other post (https://stackoverflow.com/a/32238597/969645). I just realized that I was using the higher-level of the SDK so I have to change my code like this (without defining the type):
await getClient().batchGet({
RequestItems: {
'MyTable': {
Keys: [
{'myId': 'z12345'},
{'myId': 'z12346'},
],
ProjectionExpression: 'myId, otherId',
},
},
}).promise();
Now the The provided key element does not match the schema error is gone but I still end up with Internal server error which unfortunately doesn't provide any clue in the logs. Any ideas?
BatchGet - gets the items using the primary key. In your case the PrimaryKey is NOT the partition key but both partition and sort key.
Pk = partition key AND sort key
Your code should be
await getClient().batchGet({
RequestItems: {
'MyTable': {
Keys: [
{'myId': 'z12345', 'otherId': 'whatever value'},
{'myId': 'z12346', 'otherId': 'whatever value'},
],
ProjectionExpression: 'myId, otherId',
},
},
}).promise();
Important to understand is that the UNIQUE IDENTIFIER (aka SQL id) is defined in dynamo by using both partition + sort key

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();

Serverless and GlobalSecondaryIndexes - Query condition missed key schema element with dynamodb

I tried to create GlobalSecondaryIndexes with serverless and query for it later. I get an
Query condition missed key schema element: id
error doing this, which makes sense but my plan is to query for all elements at a specific day.
var params = {
TableName: process.env.DYNAMODB_TABLE_LIGHTHOUSE,
KeyConditionExpression: 'fetchDate = :fetchDate',
ExpressionAttributeValues: {
':fetchDate': { S: '2019-05-13' }
}
};
const dbResult = await dynamoDb.query(params).promise()
console.log(dbResult)
This is the serverless part for the dynamodb. Probably here is something missing?
DynamoDbTableExpenses:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
-
AttributeName: id
AttributeType: S
-
AttributeName: fetchDate
AttributeType: S
KeySchema:
-
AttributeName: id
KeyType: HASH
GlobalSecondaryIndexes:
- IndexName: fetchDateIndex
KeySchema:
- AttributeName: fetchDate
KeyType: HASH
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE_LIGHTHOUSE}
In the web frontend it looks like this:
You need to add the IndexName attribute. Try:
var params = {
TableName: process.env.DYNAMODB_TABLE_LIGHTHOUSE,
IndexName: 'fetchDateIndex',
KeyConditionExpression: 'fetchDate = :fetchDate',
ExpressionAttributeValues: {
':fetchDate': '2019-05-13'
}
};
See API Query
The Query operation finds items based on primary key values. You can
query any table or secondary index that has a composite primary key (a
partition key and a sort key).

Dynamodb, query to fetch items in reverse order based on one of the parameter?

I am looking to fetch the chat history. Now each chat message is saved as an item in the dynamodb and I want to fetch the last say 10 msgs. I am facing issue in that.
Please see,
I have defined my table as:
chatTable:
Type: AWS::DynamoDB::Table
DeletionPolicy: Retain
Properties:
TableName: Chats
KeySchema:
- AttributeName: groupId
KeyType: HASH
- AttributeName: timestamp
KeyType: RANGE
GlobalSecondaryIndexes:
- IndexName: timestampIndex
KeySchema:
- AttributeName: groupId
KeyType: HASH
- AttributeName: timestamp
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 10
WriteCapacityUnits: 5
AttributeDefinitions:
- AttributeName: groupId
AttributeType: S
- AttributeName: timestamp
AttributeType: N
ProvisionedThroughput:
ReadCapacityUnits: 10
WriteCapacityUnits: 5
And I am trying to query to fetch chat history of one of the group as:
let getChatParams = {
TableName: "Chats",
IndexName: "timestampIndex",
Limit: 10,
ScanIndexForward: true,
KeyConditionExpression: "groupId = :groupId",
ExpressionAttributeValues: { ":groupId": groupId }
};
let groupChat = await docClient.query(getChatParams).promise();
But I am getting an error,
ValidationException: Query condition missed key schema element
Can you please help what i have to do to make this query run properly.
Thanks.
In your KeyConditionExpression you are specifying an attribute called groupId, but your partition key is called id. The Query wont work unless you specify id.

Resources