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.

DDB Enhanced: table created without indices

See original GitHub issue

Describe the Feature

DynamoDbTable.createTable() creates the table without global and local indices and there is no way how to obtain the information from TableMetadata

Is your Feature Request related to a problem?

I’m trying to create the DynamoDB table based on DDE Enhanced mappings if it does not exist but the table is created without the indices and I’m not able to get the information without any hacks.

Proposed Solution

  1. minimal solution would be to expose the key set of StaticTableMetadata.indexByNameMap in the TableMetadata interface, i.g. TableMetadata.indexNames.
  2. ideal solution is that DynamoDbTable.createTable() will prefill the request with the indices which has been read from the annotations.

Describe alternatives you’ve considered

I can use reflective access to indexByNameMap but this would be very brittle.

Additional Context

I’m trying to implement DynamoDB declarative services for Micronaut library using v2

https://agorapulse.github.io/micronaut-aws-sdk/#_declarative_services_with_service

This missing feature breaks the parity with the previous version where IDynamoDBMapper.generateCreateTableRequest() method returned the request populated with indices definitions.

  • I may be able to implement this feature request

Your Environment

  • AWS Java SDK version used: 2.11.10
  • JDK version used: 1.8
  • Operating System and version: Darwin

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:19 (13 by maintainers)

github_iconTop GitHub Comments

15reactions
oharaandrew314commented, Nov 7, 2021

@djake It definitely sucks that the sdk just ignores the indices defined in the schemas. From my understanding of the back and forth in this issue: in order to create indices, you need to know the projection and provisioned throughput, which isn’t available in the TableSchema. Arguably, this information doesn’t make sense to include in the schema for the rare scenario where you use it to create a table, so that’s why you need that ugly CreateTableEnhancedRequest to enable it.

Personally, I use the mappers to create tables all the time for my automated tests, so this missing feature is huge downer for me. I’ve been working on a plugin to make the v2 enhanced sdk palatable for kotlin data classes, and I made this helper method that seems to work well enough for my mock dynamo environment.

fun <T: Any> DynamoDbTable<T>.createTableWithIndices() {
    val metadata = tableSchema().tableMetadata()

    val globalIndices = metadata.indices()
        .filter { it.partitionKey().get().name() != metadata.primaryPartitionKey() }
        .map { index ->
            EnhancedGlobalSecondaryIndex.builder()
                .indexName(index.name())
                .projection(Projection.builder().projectionType(ProjectionType.ALL).build())
                .build()
        }

    val localIndices = metadata.indices()
        .filter { it.partitionKey().get().name() == metadata.primaryPartitionKey() && it.name() != TableMetadata.primaryIndexName() }
        .map { index ->
            EnhancedLocalSecondaryIndex.builder()
                .indexName(index.name())
                .projection(Projection.builder().projectionType(ProjectionType.ALL).build())
                .build()
        }

    val request = CreateTableEnhancedRequest.builder()
        .globalSecondaryIndices(globalIndices)
        .localSecondaryIndices(localIndices)
        .build()

    createTable(request)
}
4reactions
sullrich84commented, Apr 21, 2022

Improved @oharaandrew314 suggestion together with @denniseffing to also check if local/global secondary indices exists before creating:

fun DynamoDbAsyncTable<*>.createTableWithIndices(): CompletableFuture<Void> {
    val metadata = tableSchema().tableMetadata()

    val globalIndices = metadata.indices()
        .filter { it.partitionKey().get().name() != metadata.primaryPartitionKey() }
        .map { index ->
            EnhancedGlobalSecondaryIndex.builder()
                .indexName(index.name())
                .projection(Projection.builder().projectionType(ProjectionType.ALL).build())
                .build()
        }

    val localIndices = metadata.indices()
        .filter {
            it.partitionKey().get()
                .name() == metadata.primaryPartitionKey() && it.name() != TableMetadata.primaryIndexName()
        }
        .map { index ->
            EnhancedLocalSecondaryIndex.builder()
                .indexName(index.name())
                .projection(Projection.builder().projectionType(ProjectionType.ALL).build())
                .build()
        }

    val request = CreateTableEnhancedRequest.builder()
        .apply {
            if (localIndices.isNotEmpty()) localSecondaryIndices(localIndices)
            if (globalIndices.isNotEmpty()) globalSecondaryIndices(globalIndices)
        }
        .build()

    return createTable(request)
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Managing Global Secondary Indexes - Amazon DynamoDB
Create, modify, and delete global secondary indexes online in Amazon DynamoDB.
Read more >
Query with DynamoDB Secondary Index AWS SDK 2 Java ...
My table is idIT_RSS_Sources and I've created an index category-timestamp-index. screenshot attached of index. My code is:
Read more >
DynamoDB Enhanced Client for Java: Missing Setters Cause ...
IllegalArgumentException: Attempt to execute an operation that requires a primary index without defining any primary key attributes in the table ...
Read more >
DynamoDbTable (AWS SDK for Java - 2.18.38)
declaration: package: software.amazon.awssdk.enhanced.dynamodb, ... Creates a new table in DynamoDb with the name and schema already defined for this ...
Read more >
AWS Java SDK :: DynamoDB :: Enhanced Client 2.17.112 API
Adds a single attribute to the table schema that can be mapped between the data ... is the default attribute converter provider 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