Issue
Im trying to check if an item exists in my dynamodb table using the code below: I want to be able to run something once I can retrieve the item. The partition key is envName and the sort key is configurationName
package com.dev.newlibs;
//all relevant imports added here
public class updatenewCMDB {
public static void main(String[] args)throws Exception {
String tableName = "env_dashboard";
String configurationName = "component";
String configurationNameValue = "ec2";
String envName = "env_Name";
String envNameValue = "dev";
String status = "status";
String statusValue = "COMPLETE";
DynamoDbClient client = DynamoDbClient.builder()
.region(Region.EU_WEST_1)
.build();
client.close();
updateEnvDashboard(client, tableName, configurationName, configurationNameValue, envName, envNameValue, status, statusValue,);
}
public static void updateEnvDashboard(DynamoDbClient client,
String tableName,
String configurationName,
String configurationNameValue,
String envName,
String envNameValue,
String status,
String statusValue,) throws Exception {
//Get item to see if it exists
HashMap<String,AttributeValue> itemToGet = new HashMap<String,AttributeValue>();
itemToGet.put(configurationName, AttributeValue.builder().s(configurationNameValue).build());
itemToGet.put(status, AttributeValue.builder().s(statusValue).build());
itemToGet.put(envName, AttributeValue.builder().s(envNameValue).build());
GetItemRequest request = GetItemRequest.builder()
.key(itemToGet)
.tableName(tableName)
.build();
//run a get request and see what is returned. do something depending on what is returned
try {
Map<String,AttributeValue> returnedItem = client.getItem(request).item();
if (returnedItem != null) {
Set<String> keys = returnedItem.keySet();
System.out.println("Amazon DynamoDB table attributes: \n");
for (String key1 : keys) {
System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
}
} else {
System.out.format("No item found with the key %s!\n");
}
} catch (DynamoDbException e){
e.printStackTrace();
System.exit(1);
}
}
}
When running this i get the error:
software.amazon.awssdk.services.dynamodb.model.DynamoDbException: The provided key element does not match the schema
what am i missing here? i've tried to follow the getItem example from the official aws repo
Solution
You have to supply the key attribute(s), with the correct type(s), when calling GetItem.
You've included non-key attributes (status
). When you supply non-key attributes, your GetItem request will fail with a ValidationException including this error message:
The provided key element does not match the schema
Modify your GetItemRequest to only include key attributes (envName
and configurationName
), and ensure they have the correct data types (both strings).
To verify what's going on, it's often useful to confirm your assumptions using the awscli. Here's an example of how to issue that same GetItem call with the awscli:
aws dynamodb get-item \
--table-name mytable \
--key '{"envName":{"S":"env1"}, "configurationName":{"S":"config1"}}'
Some important background knowledge about DynamoDB: you cannot get an item without indicating its full key, which in your case is envName
plus configurationName
. If instead of a specific, single item, you actually want all items that have a given envName
then you can issue a Query (instead of GetItem) with just the envName
partition key. You cannot get/query a sort key, so you will not be able to query all items with a given configurationName
... unless you create a Global Secondary Index (GSI) on that sort key attribute and then indicate the GSI name when querying.
Answered By - jarmod