DynamoDB : The provided key element does not match the schema

115,589

Solution 1

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 2

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 3

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

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

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.

Share:
115,589

Related videos on Youtube

tripleee
Author by

tripleee

I prefer to be referred to as "they". If you are looking for something to vote on, I'm looking for **votes (ideally upvotes, natch) on the tail end** of my answers on Stack Overflow. Look at the lowest-scoring answers; downvotes as well as upvotes appreciated to help me decide what to keep, and what to kill. I'm also thinking my attempt to explain the concept of current working directory to beginners could deserve a few upvotes. The following isn't mine, unfortunately. The image is a clickable link to an archived gist of the original tweet which is now deleted.

Updated on July 09, 2022

Comments

  • tripleee
    tripleee almost 2 years

    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'
    
  • Admin
    Admin over 9 years
    Thanks Wolfwyrd.. a lot of things are clear for me now.
  • Kris White
    Kris White about 9 years
    This is an older response, but just in case someone finds this answer, it is now possible to create Global indexes on an existing table. Local indexes must still be set up at creation time.
  • Cristian Sepulveda
    Cristian Sepulveda almost 7 years
    in my case using baopham/laravel-dynamodb I have to make an explicit type using (string) and (integer): $model = ModelData::where('PartitionKey', (string)$SearchPartitionKey)->where('SortKey',(integer)$Sear‌​chSortKey)->get();
  • aviggiano
    aviggiano about 6 years
    Thank you! The problem is indeed that the AWS documentation asks for a marshalled object (e.g. var key = { "ExampleHashKey": { "S": "1" } }), while the actual SDK expects a normal javascript object (e.g. var key = { "ExampleHashKey": "1" }). This was also happening for the update/updateItem method
  • jarmod
    jarmod over 5 years
    The documentation for DynamoDB has always been a challenge. I think the root cause of the problem here is the distinction between the base DynamoDB client and the higher-level Document Client. The base client uses AttributeValues e.g. var key = { S: { name: 'joe' } } while the Document Client uses native JavaScript objects e.g. var key = { name: 'joe' }.
  • Mark Fox
    Mark Fox over 5 years
    In the case of the Ruby docs docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/… seems to be confused because the example for the Aws::DynamoDB::Client class contains the same issue of describing a marshaled value but actual expects to handle a typical hash
  • gorilla bull
    gorilla bull about 5 years
    ExampleHashKey is the id of the data entry. What does the 1 next to it stand for
  • gregn3
    gregn3 almost 4 years
    Note: apparently this solution no longer works, and now the AWS SDK behaves in accordance with the documentation, so your example would be correct in this form now: var key = { "ExampleHashKey": { S: "1"} };