skip to Main Content

I have the following schema where I am basically just trying to have a table with id as primary key, and both code and secondCode to be global secondary indexes to use to query the table.

resource "aws_dynamodb_table" "myDb" {
  name         = "myTable"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "id"

  attribute {
    name = "id"
    type = "S"
  }

  attribute {
    name = "code"
    type = "S"
  }

  attribute {
    name = "secondCode"
    type = "S"
  }

  global_secondary_index {
    name = "code-index" 
    hash_key = "code"
    projection_type = "ALL"
  }

  global_secondary_index {
    name = "second_code-index" 
    hash_key = "secondCode"
    projection_type = "ALL"
  }
}

When I try to look for one item by code

const toGet = Object.assign(new Item(), {
    code: 'code_456',
});

item = await dataMapper.get<Item>(toGet);

locally I get

ValidationException: The number of conditions on the keys is invalid

and on the deployed instance of the DB I get

The provided key element does not match the schema

I can see from the logs that the key is not being populated

Serverless: [AWS dynamodb 400 0.082s 0 retries] getItem({ TableName: 'myTable', Key: {} })

Here is the class configuration for Item

@table(getEnv('MY_TABLE'))
export class Item {
    @hashKey({ type: 'String' })
    id: string;

    @attribute({
        indexKeyConfigurations: { 'code-index': 'HASH' },
        type: 'String',
    })
    code: string;

    @attribute({
        indexKeyConfigurations: { 'second_code-index': 'HASH' },
        type: 'String',
    })
    secondCode: string;

    @attribute({ memberType: embed(NestedItem) })
    nestedItems?: Array<NestedItem>;
}

class NestedItem {
    @attribute()
    name: string;
    @attribute()
    price: number;
}

I am using https://github.com/awslabs/dynamodb-data-mapper-js

2

Answers


  1. The issue you are facing is due to calling a GetItem on an index, which is not possible. A GetItem must target a single item and an index can contain multiple items with the same key (unlike the base table), for this reason you can only use multi-item APIs on an index which are Query and Scan.

    Login or Signup to reply.
  2. I looked at the repo you linked for the package, I think you need to use the .query(...) method with the indexName parameter to tell DynamoDB you want to use that secondary index. Usuallly in DynamoDB, get operations use the default keys (in your case, you’d use get for queries on id, and query for queries on indices).

    Checking the docs, it’s not very clear – if you look at the GetItem reference, you’ll see there’s nowhere to supply an index name to actually use the index, whereas the Query operation allows you to supply one. As for why you need to query this way, you can read this: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search