question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[BUG] Local secondary indexes are not created correctly in 2.2.1

See original GitHub issue

2.2.1 introduced a bug when creating local secondary indexes. A local secondary index has the same partition key but a different sort key.

Code:

        const userSchema = new dynamoose.Schema({
            id:    {
                hashKey: true,
                type:    String,
                index:   {
                    name:     'emailIndex',
                    rangeKey: 'email',
                }
            },
            name:  {
                type:     String,
                rangeKey: true,
            },
            email: {
                type: String,
            },
        });

        const userModel = dynamoose.model('User', userSchema);

2.2.0:

aws:dynamodb:createTable:request - {
    "TableName": "User",
    "ProvisionedThroughput": {
        "ReadCapacityUnits": 1,
        "WriteCapacityUnits": 1
    },
    "AttributeDefinitions": [
        {
            "AttributeName": "id",
            "AttributeType": "S"
        },
        {
            "AttributeName": "name",
            "AttributeType": "S"
        },
        {
            "AttributeName": "email",
            "AttributeType": "S"
        }
    ],
    "KeySchema": [
        {
            "AttributeName": "id",
            "KeyType": "HASH"
        },
        {
            "AttributeName": "name",
            "KeyType": "RANGE"
        }
    ],
    "LocalSecondaryIndexes": [
        {
            "IndexName": "emailIndex",
            "KeySchema": [
                {
                    "AttributeName": "id",
                    "KeyType": "HASH"
                },
                {
                    "AttributeName": "email",
                    "KeyType": "RANGE"
                }
            ],
            "Projection": {
                "ProjectionType": "ALL"
            }
        }
    ]
}

2.2.1:

aws:dynamodb:createTable:request - {
    "TableName": "User",
    "ProvisionedThroughput": {
        "ReadCapacityUnits": 1,
        "WriteCapacityUnits": 1
    },
    "AttributeDefinitions": [
        {
            "AttributeName": "id",
            "AttributeType": "S"
        },
        {
            "AttributeName": "name",
            "AttributeType": "S"
        },
        {
            "AttributeName": "email",
            "AttributeType": "S"
        }
    ],
    "KeySchema": [
        {
            "AttributeName": "id",
            "KeyType": "HASH"
        },
        {
            "AttributeName": "name",
            "KeyType": "RANGE"
        }
    ],
    "LocalSecondaryIndexes": [
        {
            "IndexName": "emailIndex",
            "KeySchema": [
                {
                    "AttributeName": "id",
                    "KeyType": "HASH"
                },
                {
                    "AttributeName": "id",
                    "KeyType": "RANGE"
                }
            ],
            "Projection": {
                "ProjectionType": "ALL"
            }
        }
    ]
}

Response:

ValidationException: Two keys can not have the same name

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
MickLcommented, Jun 15, 2020

I can confirm the above example works like so:

        const userSchema = new dynamoose.Schema({
            id:    {
                hashKey: true,
                type:    String,
            },
            name:  {
                type:     String,
                rangeKey: true,
            },
            email: {
                type: String,
                index:   {
                    name:     'emailIndex',
                }
            },
        });

Maybe the same or a different problem was that I wanted to define a local secondary index on a table that had no range key which is forbidden:

  const userSchema = new dynamoose.Schema({
            id:    {
                hashKey: true,
                type:    String,
                index:   {
                    name:     'emailIndex',
                    rangeKey: 'email',
                }
            },
            name:  {
                type:     String,
            },
            email: {
                type: String,
            },
        });

The error message could be wrong or confusing in this case or it is not covered at all. If you do it like it correctly shows that it is not allowed:

  const userSchema = new dynamoose.Schema({
            id:    {
                hashKey: true,
                type:    String,
            },
            name:  {
                type:     String,
            },
            email: {
                type: String,
                index: {
                    global: true,
                    name:     'emailIndex',
                    rangeKey: 'email',
                }
            },
        });
0reactions
fishcharliecommented, Jun 9, 2020

I totally understand the reasoning behind why it makes more sense to have indices be defined as separate than the attribute. Especially in cases for a rangeKey.

However, this would be a breaking change, and v3 is barely even on my radar at this point. So for now, this conversation is very off topic.

@sturcotte06 I will note. That I’d be open to explore adding an additional setting to define indices (and not removing existing methods) like shown above. That is something I’d be open to for sure. However, I don’t think that is what you mean since you mentioned I'm all in for a single way of defining indices.

To date, I’ve never heard a truly compelling reason for why overloads, or having multiple ways to achieve one thing, is a bad idea. Except for the fact that it’s more work to maintain. So long as the documentation discusses all methods (which it does as far as I’m aware) it’s fine. The reality is currently, I’m the primary maintainer of Dynamoose, so it just adds more work for me to maintain. There is no downside for users to adding more methods to do a single task. If someone has a compelling argument for why having multiple ways to do things is bad, I’d love to hear it.


If anyone wants to make any of those arguments, feel free to contact me (outside of this issue). Or if you want to submit a proposal for an additional way to define indices, let’s create another issue.

That way we can stay on topic here.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Local Secondary Indexes - Amazon DynamoDB
Retrieve data quickly from a local secondary index that has a composite primary key (partition key and sort key) with Amazon DynamoDB.
Read more >
Navigation | Android Developers
Declaring dependencies. To add a dependency on Navigation, you must add the Google Maven repository to your project.
Read more >
4.1 Specifying Partitioning When Creating Tables and Indexes
You can create nonpartitioned global indexes, range or hash partitioned global indexes, and local indexes on partitioned tables. When you create (or alter) ......
Read more >
How are indexes stored and updated? | Apache Cassandra 2.2
These indexes are stored locally on each node in a hidden table and built in a background process. If a secondary index is...
Read more >
Web Content Accessibility Guidelines (WCAG) 2.1 - W3C
WCAG 2.1 success criteria are written as testable statements that are not technology-specific. Guidance about satisfying the success criteria in ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found