I have DynamoDB table with Hashkey + RangeKey. I am facing the following error while deleting an entry for a given HashKey and RangeKey.
Tried following approaches
Used a DynamoDBMapper to get the record (Obj) from DB using DynamoDBQueryExpression that includes both HashKey + RangeKey in KeyCondition. Performed dynamoDBMapper.delete(Obj).
Referred to other post - DynamoDb: Delete all items having same Hash Key and tried
HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>();
eav.put(":v1", new AttributeValue().withS(value));
DynamoDBQueryExpression<DocumentTable> queryExpression = new DynamoDBQueryExpression<DocumentTable>()
.withKeyConditionExpression("documentId = :v1")
.withExpressionAttributeValues(eav);
List<DocumentTable> ddbResults = dynamoDBMapper.query(DocumentTable.class, queryExpression);
dynamoDBMapper.batchDelete(ddbResults);
In both the above cases I see the following exception
com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException: The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: I12MUB0FSQNAQT6AH0RHE1B12JVV4KQNSO5AEMVJF66Q9ASUAAJG)
Please help in case someone had similar issues.
Is it not recommended to have a composite Key ( as HashKey and SortKey )?
You tried to specify an item by giving a value for the key documentId. The error is trying to tell you that documentId isn't the name of the key in your table.
Replace documentId with the name of the key in you table.
Related
I want to do conditional putItem call into DynamoDb i.e. don't insert an entry in dynamoDb if the primaryKey(partitionKey + Sort Key already exists). My schema's key look like this:
PartitionKey: abc:def
SortKey:abc:123
To do a conditional I do something like this:
private static final String PK_DOES_NOT_EXIST_EXPR = "attribute_not_exists(%s)";
final String condition = String.format(PK_DOES_NOT_EXIST_EXPR,
record.getPKey() + record.getSortKey);
final PutItemEnhancedRequest putItemEnhancedRequest = PutItemEnhancedRequest
.builder(Record.class)
.conditionExpression(
Expression.builder()
.expression(condition)
.build()
)
.item(newRecord)
.build();
However I run into following error
Exception in thread "main" software.amazon.awssdk.services.dynamodb.model.DynamoDbException: Invalid ConditionExpression: Syntax error; token: ":123", near: "abc:123)" (Service: DynamoDb, Status Code: 400
I am assuming this is because of : present in my condition, because the same expression without : in the key succeeds. Is there a way to fix this?
Your condition should include the name of the partition key attribute, not its value. For example:
attribute_not_exists(pk)
Also, see Uniqueness for composite primary keys for an explanation of why you only need to indicate the partition key attribute name, not both the partition key and the sort key attribute names. So, the following, while not harmful, is unnecessary:
attribute_not_exists(pk) AND attribute_not_exists(sk)
I would like some help; i'm trying to get a certain item from the dynamodb table by calling it with the specific id (primary key) e with a global secondary index called index_book.
The function of interest is as follows:
case "GET /book/{id}":
body = await dynamo
.get({
TableName: "book",
Key: {
id: event.pathParameters.id
}
})
.promise();
break;
The moment I go to call the url with a specific id, so for example /book/7 (where 7 is id)
I get the following error:
"The provided key element does not match the schema"
Can you help me please? I will be very grateful to you.
You cannot do a get item against a GSI, you have to do a query. That's because in a GSI there's no uniqueness constraint and multiple items might have the same partition key / sort key combination.
So switch the get to a query and you'll also need to specify the IndexName.
I've seen this page about how to query with partition keys only. However, my case is using DynamoDBMapper class to make the query, what seemed to work there does not apply.
Here's a part of my code:
private final DynamoDBMapper mapper;
List<QueryResult> queryResult = mapper.query(QueryResult.class, queryExpression);
The table I query has a primary partition key id and primary sort key timestamp.
I wanted to query all the rows with designatedid, eav looks like:
{:id={S: 0123456,}}
but if the id has duplicates (which makes sense cause it's partition key), it always gives me
"The provided key element does not match the schema"
Not sure how to resolve this. Due to sharing code with other tables, DynamoDBMapper class is a must.
Any help appreciated! Thanks.
Does the below work?
final DynamoDBQueryExpression<QueryResult> queryExpression = new DynamoDBQueryExpression<>();
expression.setKeyConditionExpression("id = :id");
expression.withExpressionAttributeValues(ImmutableMap.of(":id", new AttributeValue("0123456")));
Here is a working example:
final MyItem hashKeyValues = MyItem.builder()
.hashKeyField("abc")
.build();
final DynamoDBQueryExpression<MyItem> queryExpression = new DynamoDBQueryExpression<>();
queryExpression.withHashKeyValues(hashKeyValues);
queryExpression.setConsistentRead(false); //or true
final PaginatedQueryList<MyItem> response = dynamoDBMapper.query(MyItem.class, queryExpression);
The image below show my table's structure
And try to querying the list of item with Java code below:
QuerySpec qs = new QuerySpec()
.withKeyConditionExpression("RecordID >= :v_recordID")
.withFilterExpression("DeviceID = :v_deviceID")
.withValueMap(new ValueMap()
.withInt(":v_recordID", recordID)
.withString(":v_deviceID", deviceID)
);
I wanna to get items with RecordID greater than or equal 5, but it got an error:
Query key condition not supported
How to solve it, thanks in advance !
Check out link : http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html
The partition key equality test is required, and must be specified in the following format:
partitionKeyName = :partitionkeyval
I am trying to use the Java AWS sdk to get a document based on a Global Secondary Index.
Setup as follows:
Hash Key: MyId - Number
Range Key: MyDate - String
Here is my code to:
Map<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put("MyId", new AttributeValue().withN("1234"));
key.put("MyDate", new AttributeValue().withS("2014-10-12"));
GetItemRequest go = new GetItemRequest().withTableName(tableName).withKey(key);
GetItemResult result = getDynamoDBClient().getItem(gi);
But this always returns :
The provided key element does not match the schema (Service:
AmazonDynamoDBv2; Status Code: 400
What am I dong wrong?
A few notes, first you talk about GSI but you are doing GetItemRequest by primary key. So perhaps you're missing something in your question.
Did you write in your question the primary key of the table or the GSI definition?
You can only Query by GSI, Get is still based on primary key.