99x / serverless-dynamodb-local

Serverless Dynamodb Local Plugin - Allows to run dynamodb locally for serverless
MIT License
624 stars 233 forks source link

Global Secondary Index is not working #270

Open yukitaka13-1110 opened 3 years ago

yukitaka13-1110 commented 3 years ago

I defined dynamodb table with global secondary index. I requested query with GSI. But an error occurred. Is This plugin not support GSI?

request.vtl

{
    "version" : "2017-02-28",
    "operation" : "Query",
    "index" : "groupId-index",
    "query" : {
        "expression": "groupId = :groupId",
        "expressionValues" : {
            ":groupId" : $util.dynamodb.toDynamoDBJson($ctx.args.groupId)
        }
    }
}

serverless.yml

resources:
  Resources:
    UserTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: UserTable
        KeySchema:
          -
            AttributeName: id
            KeyType: HASH
        AttributeDefinitions:
          -
            AttributeName: id
            AttributeType: S
          -
            AttributeName: groupId
            AttributeType: S
        BillingMode: PAY_PER_REQUEST

        GlobalSecondaryIndexes:
          -
            IndexName: groupId-index
            KeySchema:
              - AttributeName: groupId
                KeyType: HASH
            Projection:
              ProjectionType: ALL

Error

Error while executing Local DynamoDB
{
    "version": "2017-02-28",
    "operation": "Query",
    "index": "groupId-index",
    "query": {
        "expression": "groupId = :groupId",
        "expressionValues": {
            ":groupId": {
                "S": "group-001"
            }
        }
    }
}
ValidationException: The table does not have the specified index: groupId-index
plugins:
  - serverless-appsync-plugin
  - serverless-dynamodb-local
  - serverless-appsync-simulator
  - serverless-offline
majindageta commented 3 years ago

Hello, maybe is an issue with your code. I can use global and local secondary index just fine. Check the indentation on your YAML, try to create a smaller yaml with just an index.

this is my YAML that works:

Resources:
  kraken:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:custom.krakenTableName}
      AttributeDefinitions:
        - AttributeName: PK
          AttributeType: S
        - AttributeName: SK
          AttributeType: S
        - AttributeName: guidChannelRaw
          AttributeType: S
      KeySchema:
        - AttributeName: PK
          KeyType: HASH
        - AttributeName: SK
          KeyType: RANGE
      BillingMode: PAY_PER_REQUEST
      GlobalSecondaryIndexes:
      - IndexName: chRawRef-index
        KeySchema:
        - AttributeName: guidChannelRaw
          KeyType: HASH
        Projection: 
          ProjectionType: ALL         
Hideman85 commented 2 years ago

For me the index is working and present but always empty, result that the query returns nothing. I tried to see if it was not a spelling mistake in any of the attribute but nothing.

    TestTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        KeySchema:
          -
            AttributeName: id
            KeyType: HASH
        AttributeDefinitions:
          -
            AttributeName: id
            AttributeType: S
          -
            AttributeName: organisationID
            AttributeType: S
          -
            AttributeName: createdAt
            AttributeType: S
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: 'Test'
        GlobalSecondaryIndexes:
          -
            IndexName: organisationID
            KeySchema:
              -
                AttributeName: organisationID
                KeyType: HASH
              -
                AttributeName: createdAt
                KeyType: RANGE
            Projection:
              ProjectionType: ALL
            ProvisionedThroughput:
              ReadCapacityUnits: 1
              WriteCapacityUnits: 1
$ aws dynamodb describe-table --table-name Test --endpoint-url http://localhost:8888
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "id",
                "AttributeType": "S"
            },
            {
                "AttributeName": "organisationID",
                "AttributeType": "S"
            },
            {
                "AttributeName": "createdAt",
                "AttributeType": "S"
            }
        ],
        "TableName": "Test",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2021-11-13T10:39:00.009000+01:00",
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": "1970-01-01T01:00:00+01:00",
            "LastDecreaseDateTime": "1970-01-01T01:00:00+01:00",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 1,
            "WriteCapacityUnits": 1
        },
        "TableSizeBytes": 1256,
        "ItemCount": 8,
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Test",
        "GlobalSecondaryIndexes": [
            {
                "IndexName": "organisationID",
                "KeySchema": [
                    {
                        "AttributeName": "organisationID",
                        "KeyType": "HASH"
                    },
                    {
                        "AttributeName": "createdAt",
                        "KeyType": "RANGE"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1
                },
                "IndexSizeBytes": 1256,
                "ItemCount": 0,
                "IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Test/index/organisationID"
            }
        ]
    }

$ aws dynamodb scan --table-name Test --endpoint-url http://localhost:8888
{
    "Items": [
        {
            "organisationID": {
                "S": "org-test"
            },
            "_deleted": {
                "BOOL": false
            },
            "name": {
                "S": "Test"
            },
            "_rev": {
                "S": "1-9479cd8b87afd68fd0194a209b364dd3"
            },
            "id": {
                "S": "testID"
            },
            "status": {
                "S": "drafting"
            },
            "updatedAt": {
                "S": "2021-11-13T09:42:52.681Z"
            }
        },
        ...
    ]
}
aws dynamodb query --table-name Test --index-name organisationID --key-condition-expression 'organisationID = :org' --expression-attribute-values '{":org": { "S": "org-test" }}' --endpoint-url http://localhost:8888
{
    "Items": [],
    "Count": 0,
    "ScannedCount": 0,
    "ConsumedCapacity": null
}

Any idea? I'm blocked in my local testing since I cannot replicate the remote behavior.

Hideman85 commented 2 years ago

My bad if you range key is empty it won't be indexed, in my sample the mistake is I wanted to index organisationID, updatedAt not createdAt