0

My device collects some data and sends it AWS using its IoT MQTT interface. My lambda reads the data and saves it to DynamoDB. Below is one sample record in my dynamo, where timeStamp is a primary partition key.

 Item{3}     

 message          String:   DOWN     

 payloadMap{4}

   direction      String:   -

   message        String:   DOWN

   timeStamp      String:   2018-08-30 07:18:09.247373

   value          String:     -70.0000    

 timeStamp      String: 2018-08-30 07:18:09.247373

Then I am trying to query dynamo back on my small node app and I cannot access the data using below script:

dynamodb.getItem({
      TableName: 'myTableName',
      Key: {
        'timeStamp' : {'S': '2018-08-30 07:18:09.247373'}
      }
    },(err,result)=>{
      if(err){
        console.log(err);
      }
      else {
        console.log('success');  
      }
    });

Below is my dynamoDB initialization:

function initDynamoAWS(){
  AWS.config.apiVersion = {dynamodb: '2012-08-10'};
  AWS.config.update({accessKeyId:access_key_id,
                     secretAccessKey:secret_access_key,
                     region:'us-west-2'});
  dynamodb = new AWS.DynamoDB({ARN:ARN});
}

All credentials are fine as I can get dynamodb.describeTable with all the details but I cannot get a single item from my table but all I can get is "Error: The provided key element does not match the schema". What am I missing ?

When I changed the code to:

    let params = {};
    let key = {'timeStamp' :'2018-08-30 07:18:09.247373'};
    params.TableName = 'myTableName';
    params.Key = key;
    dynamodb.getItem(params,(err,result)=>{
      if(err){
        // debugger;
        console.log(err);
      }
      else {
        console.log('success');  
      }
    });

I am getting a different error: "InvalidPatemeterType: Expected params.Key['timeStamp'] to be a structure" "UnexpectedPatameter: Unexpected key '0' found in params.Key['timeStamp']"...and the same error for numbers up to 25.

I can get below details about my table from AWS via "describe table"

Table : AttributeDefinitions : 
  Array(2) 
     0 : AttributeName : "message"
         AttributeType : "S"
     1 : AttributeName : "timeStamp" 
         AttributeType : "S"
     ItemCount : 42 
TableSizeBytes : 5434 TableStatus : "ACTIVE"
KeySchema:
  Array(2)
  0:{AttributeName: "timeStamp", KeyType: "HASH"}
  1:{AttributeName: "message", KeyType: "RANGE"}
marcinwal
  • 169
  • 10
  • 2
    Do you have an up to date AWS node SDK? Can you show us the code that initializes the dynamodb variable? Finally, tell me if Key: { timeStamp: '2018-08-30 07:18:09.247373' } works for you. – jarmod Sep 03 '18 at 22:34
  • I added my dynamodb init; regarding the query I tried it in my console as a query and it worked fine and gave me the expected result – marcinwal Sep 04 '18 at 08:52
  • Check [DynamoDB : The provided key element does not match the schema](https://stackoverflow.com/a/33534945/420552) and notice that the `Key` component should be just `{'timeStamp' : '2018-08-30 07:18:09.247373'}` as @jarmod correctly pointed out – laika Sep 04 '18 at 09:04
  • I changed the structure of the query and error is different now (above in question box) – marcinwal Sep 04 '18 at 11:09

1 Answers1

1

The problem is that your table has a composite primary key of timeStamp + message. In order to get an item from this table you need to supply the complete key for the item. You are only supplying the timeStamp.

If you want to find all items that match a specific timestamp, then you need to use query rather than getItem.

Here is an example of using query:

const params = {
  ExpressionAttributeValues: {
    ':v1': {
      S: '2018-08-30 07:18:09.247373',
    },
  },
  KeyConditionExpression: '#t = :v1',
  ExpressionAttributeNames: { '#t': 'timeStamp' },
  TableName: 'myTableName',
};

dynamodb.query(params, (err, data) => {
  if (err) {
    console.log('query error:', err);
  } else {
    console.log('query data:', data);
  }
});

Note that timeStamp is a DynamoDB reserved word. If you need to write an expression containing an attribute name that conflicts with a DynamoDB reserved word, you need to define an expression attribute name to use in the place of the reserved word. I've used #t for timeStamp in this example.

PS it's unusual for a partition key to be a timestamp. Typically a timestamp would be the sort key and, in your case, message would be a simple attribute of the item rather than the sort key. You may need to rethink your DB schema. If you're simply looking for a unique, opaque identifier then you can use a UUID.

jarmod
  • 71,565
  • 16
  • 115
  • 122