70

I'm trying to update an Item in my Dynamodb Table +Users+. I have tried many different ways but I always received the same error message:

The provided key element does not match the schema

The creation of an Item works, as well as a query but not the update. When I check on DynamoDB the user is well created:

{
  "email": "test@email.com",
  "password": "123",
  "registration": 1460136902241,
  "verified": false
}

Here is the table information:

  • Table name: Users
  • Primary partition key: email (String)
  • Primary sort key: registration (Number)

Here is the code (called from lambda):

exports.handler = function(event, context)
{
    var AWS = require("aws-sdk");


    var docClient = new AWS.DynamoDB.DocumentClient();

    var params = {
        TableName: "Users",
        Item:{
            email: "test@email.com",
            password: "123",
            verified: false,
            registration: (new Date()).getTime(),
        }
    };

    // Create the user.

    docClient.put(params, function(err, data)
    {
        if (err)
        {
            context.fail("Put failed...");
            return;
        }

        var params = {
            TableName: "Users",
            Key: { email : "test@email.com" },
            AttributeUpdates: {
                verified: {
                    Action: "PUT",
                    Value: true
                }
            }
        };

        // Update the user.
        docClient.update(params, function(err, data)
        {
            if (err)
            {
                console.log(JSON.stringify(err));
                context.fail(JSON.stringify(err));
                return;
            }
            context.succeed("User successfully updated.");
        });


    });

};

Do you have any idea of what could be wrong in my code?

Mark B
  • 183,023
  • 24
  • 297
  • 295
user6178502
  • 715
  • 1
  • 5
  • 7

7 Answers7

134

You are only providing half of your primary key. Your primary key is a combination of the partition key and range key. You need to include the range key in your Key attribute in the update parameters.

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • 1
    It works, thank you! But is it possible to have only the email address as primary key ? – user6178502 Apr 09 '16 at 01:59
  • Yes it is possible to have only email address as primary key. http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SampleData.CreateTables.html – auhuman Dec 01 '17 at 11:03
  • Maybe typos in key name, it happened for me – Nazeel Dec 30 '19 at 14:43
  • 11
    If you still want to query by PK only, you have to use 'query', not 'get' method. In this case you can provide KeyConditionExpression: 'PK = xxx' only. – Dmitry Zlykh Nov 27 '20 at 09:01
  • 1
    I don't have a range key in my table, and I am providing the partition key, but getting this error when I'm calling deleteItem. Are there any other cases that may cause this error? – Azamat Abdullaev Aug 18 '21 at 16:33
  • What specifically is the syntax for the query object? I am using AWS SDK version 2 – Mark A Dec 16 '21 at 19:05
  • @MarkA why would you tack onto an old question to ask this? I'm not going to paste the syntax into an unformatted comment here. I would just be copy/pasting from the official docs anyway. I suggest you read the documentation: https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-dynamodb-items.html – Mark B Dec 16 '21 at 20:13
  • @MarkB I used the docs. I added it here because even after digging through the docs and using the simple object for the composite Key with the partition key and secondary key, it still didn't work. Your original answer makes perfect sense. An example with old or new syntax would have been helpful, for any language, Java or JS. I updated to v3, & then the simple object with partition key and secondary key worked fine. – Mark A Dec 18 '21 at 06:30
  • Thanks. I had accidentally annotated another column as "@DynamoDBRangeKey" when I shouldn't have. – btraas Jan 23 '22 at 21:20
24

For others who have faced the same challenge and the issue is not fixed by above answers, it is always better to double check the data type of the value being updated, in my case the primary key was expecting a Number and I was trying to update with a string. Silly me

  • 2
    I also had a silly issue. My table was created with a composite key (i.e. a primary key AND a sort key). When in reality, I only wanted a primary key experience. Lesson learned--plan ahead! – crftr Feb 08 '22 at 22:56
6

My issue was with the Node SDK for deletes, where the documentation says to provide in format:

... {Key: {'id': {S: '123'}}} ...

Which does not appear to work with the aws-sdk ^2.1077.0. This seems to work:

... {Key: {'id': '123'}} ...
plantbeard
  • 358
  • 7
  • 16
1

My checklist when facing this issue:

  1. Check that the name and type of your key correspond to what you have in the database.
  2. Use corresponding attributes to make it explicit. E.g. use @DynamoDBHashKey(attributeName = "userId") in Java to indicate the partition key named userId.
  3. Ensure that only one field or getter marked as partition key in your class.

Please, add more if you know in the comments.

Sergei Russkikh
  • 123
  • 1
  • 7
1

I was doing BatchGetItem, then streamed it to BatchWriteItem (Delete). DeleteItem didn't like it got all attributes from the object instead of only partition and sort key.

Gathering all answers:

  • mismatch in an attribute name
  • mismatch in attribute type
  • half key provided
  • unnecessary additional keys
double-beep
  • 5,031
  • 17
  • 33
  • 41
nouveu
  • 162
  • 4
  • 9
1
  • assuming you are using "@aws-sdk/client-dynamodb" in NodeJS

  • if you have both sort key(ex. post_id) and range key(ex. user_id) in your table(ex. UserPostTable), and if you are updating this table with other attribute(for example image_url) then.

  • you need to specify both sort key and range key as well

      const updateParams = {
    TableName: process.env.TABLE_NAME,
    Key: {
      post_id: { S: post_id },
      user_id: { S: user_id },
    },
    UpdateExpression: "SET image_url = :url",
    ExpressionAttributeValues: { ":url": { S: image_url } },};const updateCommand = new UpdateItemCommand(updateParams);
    
abhish
  • 243
  • 4
  • 8
0

For the error,

The provided key element does not match the schema

There could be two possible problems here:

  1. You are only providing half of your primary key. For the primary key, you must provide all of the attributes. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key.
  2. Field's value should have a proper data type as per the table. It is always better to double-check the data type of the value being passed. Maybe, you have defined the primary key as a Number and you are passing a string value in the getItem call.

Hope it helps.

Please add more if there could be other possible reasons.

Arpit Jain
  • 1,599
  • 9
  • 23