DynamoDB : The provided key element does not match the schema

PythonAmazon Web-ServicesAmazon DynamodbBoto

Python Problem Overview


Is there a way to get an item depending on a field that is not the hashkey?

Example

My Table Users: id (HashKey), name, email

And I want to retrieve the user having email as '[email protected]'

How this can be done?

I try this with boto:

user = users.get_item(email='[email protected]')

I get the following error:

'The provided key element does not match the schema'

Python Solutions


Solution 1 - Python

The following applies to the Node.js AWS SDK in the AWS Lambda environment:

This was a rough one for me. I ran into this problem when trying to use the getItem method. No matter what I tried I would continue to receive this error. I finally found a solution on the AWS forum: https://forums.aws.amazon.com/thread.jspa?threadID=208820

Inexplicably, the apparent solution conflicts with all AWS documentation that I can find.

Here is the code which worked for me:

var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();

var params = { }
params.TableName = "ExampleTable";
var key = { "ExampleHashKey": "1" };
params.Key = key;
    
dynamo.getItem(params, function(err, data) {
    if (err)
        console.log(err);
    else
        console.log(data)
});

Solution 2 - Python

To query on fields which are not the hash key you need to use a Global Secondary Index (GSI). Take a look at this AWS Post for more details on GSI's.

UPDATE Feb 2015: It is now possible to add a GSI to an existing table. See the Amazon Docs for more details.

Sadly you cannot add a GSI to an existing DynamoDB table so you'll need to create a new table and port your data if this is something you really need to query on.

From the DynamoDB FAQ:

> Q: How do I create a global secondary index for a DynamoDB table? > > All GSIs associated with a table must be specified at table creation > time. At this time, it is not possible to add a GSI after the table > has been created. For detailed steps on creating a Table and its > indexes, see here. You can create a maximum of 5 global secondary > indexes per table.

If you do not want to port your data you could consider creating a second DynamoDB table with the email as a hash key and the hash of the parent record to use as a lookup into your main data table but as you can imagine this isn't exactly an optimal solution and it comes with its own headaches of keeping it in synch with your master table.

Solution 3 - Python

I also got this error when I was sending a string instead of an integer.

Of course, this was when I was writing to the database, rather than reading from.

Solution 4 - Python

I have a partition key and a sort key on my table.

I was querying it with only the partition key, and I got this error.

Obviously, querying the composite key fixed it.

Solution 5 - Python

I got this error in Java because I had used the @DynamoDBHashKey annotation for a RANGE key. I had to use the @DynamoDBRangeKey annotation for my object's id instead.

Solution 6 - Python

I got this error in my Java application, because I accidentally had two Range keys annotated (@DynamoDBRangeKey) in my DAO class, when there should only be one. I changed the new addition's annotation to @DynamoDBAttribute, and that solved it.

Solution 7 - Python

I got this error in my AWS Lambda function, because my parameters was BigInt and needed to be converted to Number. I changed this:

let data = await docClient.get({ TableName: "items", Key: { "accountid": accountId, "itemid": itemId } }).promise();

... to this:

let data = await docClient.get({ TableName: "items", Key: { "accountid": Number(accountId), "itemid": Number(itemId) } }).promise();

Solution 8 - Python

In case it helps anyone else just starting out with DynamoDB, I got this error when trying to use GetItemCommand and only providing a Partition key on a table with a composite Primary key.

Either additionally specify a value for the Sort key to retrieve the single record that matches that combination, or switch to QueryCommand to return anything matching just the partition key regardless of the Sort key.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1635536View Question on Stackoverflow
Solution 1 - PythonSeanView Answer on Stackoverflow
Solution 2 - PythonWolfwyrdView Answer on Stackoverflow
Solution 3 - PythonNotoriousWebmasterView Answer on Stackoverflow
Solution 4 - PythonBenView Answer on Stackoverflow
Solution 5 - PythonRyan ShillingtonView Answer on Stackoverflow
Solution 6 - PythonJoshView Answer on Stackoverflow
Solution 7 - PythonFredrik JohanssonView Answer on Stackoverflow
Solution 8 - PythonMike D SuttonView Answer on Stackoverflow