User403768921
User403768921

Reputation: 55

Create dynamodb table from JSON

I'm trying to create a dynamo table in my code through a JSON file which contains the structure of my table. Now i'm creating the table with the following code:

amazonClient.createTable(
        CreateTableRequest()
            .withTableName(tableName)
            .withKeySchema(KeySchemaElement("id", KeyType.HASH))
            .withAttributeDefinitions(...)
            .withProvisionedThroughput(...)
            .withGlobalSecondaryIndexes(...))

Is it possible to create it via JSON?

Upvotes: 4

Views: 1815

Answers (2)

camelstrike
camelstrike

Reputation: 11

I now this is already answered but you can use the provided class CreateTableRequest together with an object mapper such as Gson.

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class InitTables {

    private AmazonDynamoDB dynamoDB;

    private static String musicTable = "{\n" +
        "  \"TableName\" : \"Music\",\n" +
        "  \"KeySchema\": [\n" +
        "    {\n" +
        "      \"AttributeName\": \"Artist\",\n" +
        "      \"KeyType\": \"HASH\"\n" +
        "    },\n" +
        "    {\n" +
        "      \"AttributeName\": \"SongTitle\",\n" +
        "      \"KeyType\": \"RANGE\"\n" +
        "    }\n" +
        "  ],\n" +
        "  \"AttributeDefinitions\": [\n" +
        "    {\n" +
        "      \"AttributeName\": \"Artist\",\n" +
        "      \"AttributeType\": \"S\"\n" +
        "    },\n" +
        "    {\n" +
        "      \"AttributeName\": \"SongTitle\",\n" +
        "      \"AttributeType\": \"S\"\n" +
        "    }\n" +
        "  ],\n" +
        "  \"ProvisionedThroughput\": {\n" +
        "    \"ReadCapacityUnits\": 1,\n" +
        "    \"WriteCapacityUnits\": 1\n" +
        "  }\n" +
        "}";


    public InitTables(AmazonDynamoDB dynamoDB) {
        this.dynamoDB = dynamoDB;
        init();
    }

    public void init() {
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                .create();
        CreateTableRequest createTableRequest = gson.fromJson(musicTable, CreateTableRequest.class);
        dynamoDB.createTable(createTableRequest);
    }
}

Upvotes: 1

João Matos
João Matos

Reputation: 7020

I was also trying to achieve something similar but I didn't find any lib for that purpose, hence I took a few minutes to code it myself.

Provided with a json file structured the same way as in the documentation example:

{
    TableName : "Music",
    KeySchema: [
        {
            AttributeName: "Artist",
            KeyType: "HASH", 
        },
        {
            AttributeName: "SongTitle",
            KeyType: "RANGE" 
        }
    ],
    AttributeDefinitions: [
        {
            AttributeName: "Artist",
            AttributeType: "S"
        },
        {
            AttributeName: "SongTitle",
            AttributeType: "S"
        }
    ],
    ProvisionedThroughput: {       
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1
    }
} 

The code bellow works. Note that:

  • The createTable method expects a json string, which you can obtain using something like Files.readString(Path.of("path/to/your/file.json"))
  • if you do not use Lombok you have to create constructors/getters/setters yourself
  • the @JsonProperty annotations are only necessary if the class field names are not an exact match to the json ones (in this case, the first letter is uppercase), explained here.

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.model.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
    public class CreateTable {
        private final AmazonDynamoDB amazonDynamoDB;
    
        public void createTable(String json) throws JsonProcessingException {
            Table table = readTable(json);
            amazonDynamoDB.createTable(getTableRequest(table));
        }
    
        private CreateTableRequest getTableRequest(Table table) {
            return new CreateTableRequest()
                    .withTableName(table.getTableName())
                    .withKeySchema(toKeySchemaElement(table.getKeySchema()))
                    .withAttributeDefinitions(toAttributeDefinition(table.getAttributeDefinitions()))
                    .withProvisionedThroughput(toProvisionedThroughput(table.getProvisionedThroughput()));
        }
    
        private Table readTable(String json) throws JsonProcessingException {
            return new ObjectMapper().readValue(json, Table.class);
        }
    
        private ProvisionedThroughput toProvisionedThroughput(ProvisionedTp provisionedTp) {
            log.info("creating provisioned throughput read: {} write: {}", provisionedTp.getReadCapacityUnits(), provisionedTp.getWriteCapacityUnits());
            return new ProvisionedThroughput(provisionedTp.getReadCapacityUnits(), provisionedTp.getWriteCapacityUnits());
        }
    
        private Collection<AttributeDefinition> toAttributeDefinition(Collection<AttributeDef> attributeDefs) {
            return attributeDefs.stream().map(this::toAttributeDefinition).collect(Collectors.toList());
        }
        
        private AttributeDefinition toAttributeDefinition(AttributeDef attributeDef) {
            log.info("creating new attribute definition {}: {}", attributeDef.getAttributeName(), attributeDef.getAttributeType());
            return new AttributeDefinition().withAttributeName(attributeDef.getAttributeName()).withAttributeType(attributeDef.getAttributeType());
        }
    
        private Collection<KeySchemaElement> toKeySchemaElement(Collection<KeySchema> keySchemas) {
            return keySchemas.stream().map(this::toKeySchemaElement).collect(Collectors.toList());
        }
    
        private KeySchemaElement toKeySchemaElement(KeySchema keySchema) {
            log.info("creating new key schema element {}: {}", keySchema.getAttributeName(), keySchema.getKeyType());
            return new KeySchemaElement().withAttributeName(keySchema.getAttributeName()).withKeyType(keySchema.getKeyType());
        }
    
        @Data
        @NoArgsConstructor
        public static class Table {
            @JsonProperty("TableName")
            private String tableName;
            @JsonProperty("KeySchema")
            private List<KeySchema> keySchema;
            @JsonProperty("AttributeDefinitions")
            private List<AttributeDef> attributeDefinitions;
            @JsonProperty("ProvisionedThroughput")
            private ProvisionedTp provisionedThroughput;
        }
    
        @Data
        @NoArgsConstructor
        public static class KeySchema {
            @JsonProperty("AttributeName")
            private String attributeName;
            @JsonProperty("KeyType")
            private String keyType;
        }
    
        @Data
        @NoArgsConstructor
        public static class AttributeDef {
            @JsonProperty("AttributeName")
            private String attributeName;
            @JsonProperty("AttributeType")
            private String attributeType;
        }
    
        @Data
        @NoArgsConstructor
        public static class ProvisionedTp {
            @JsonProperty("ReadCapacityUnits")
            private long readCapacityUnits;
            @JsonProperty("WriteCapacityUnits")
            private long writeCapacityUnits;
        }
    
    }
    

  

Upvotes: 2

Related Questions