【问题标题】:DynamoDB and TableNameOverride with prefixDynamoDB 和 TableNameOverride 带前缀
【发布时间】:2014-01-20 05:33:33
【问题描述】:

我正在测试 DynamoDB 表,并希望为 prod 和 dev 环境设置不同的表名,使用前缀“dev_”进行开发。

我做了这个测试来打印表名:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.TableNameOverride;  

TableNameOverride tbl = new TableNameOverride("test").withTableNamePrefix("dev_");
System.out.println("name=" + tbl.getTableName() + "  prefix=" + tbl.getTableNamePrefix());

这打印:name=null prefix=dev_
这里的名字怎么是空的?

TableNameOverride tbl = new TableNameOverride("test");//.withTableNamePrefix("dev_");
System.out.println("name=" + tbl.getTableName() + "  prefix=" + tbl.getTableNamePrefix());

打印:name=test prefix=null

*如何让表名成为“dev_test”?*

我想稍后使用它为开发模式下的所有表获取“dev_”前缀,如下所示:

DynamoDBTable annotation = (DynamoDBTable) myclass.getClass().getAnnotation(DynamoDBTable.class);  
TableNameOverride tbl = new TableNameOverride(annotation.tableName()).withTableNamePrefix("dev_");

或者是否有另一种解决方案来分隔开发表和产品表?
我首先想到将它们放在不同的区域,但不确定。

也可以这样用:

mapper.save(ck, new DynamoDBMapperConfig(new TableNameOverride((isDev ? "dev_" : "") + annotation.tableName())));

【问题讨论】:

    标签: java amazon-dynamodb


    【解决方案1】:

    我也遇到过同样的情况,并与自己苦苦挣扎了几天才能让它发挥作用。

    以防万一您使用的是 DynamoDB + Spring,这对我有用:

    POJO 类:

    @DynamoDBTable(tableName = "APP-ACCESSKEY")
    public class AccessKey {
        @NotBlank
        @Size(min = 1, max = 36)
        private String accessToken;
    
        @NotNull
        @Size(min = 3, max = 15)
        private String userName;
    
        private Date dateInsertion;
    
    
        public AccessKey() {
    
        // ... All POJO stuff
    }
    

    弹簧配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
              http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    
        <!-- Amazon Credentials -->
        <bean id="tableNameOverride" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="staticMethod" value="com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix"/>
            <property name="arguments" value="DES-" />
        </bean>
    
        <bean id="dynamoDBMapperConfig" class="com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig">
            <constructor-arg index="0" ref="tableNameOverride" />
        </bean>
    
        <bean id="BasicAWSCredentials" class="com.amazonaws.auth.BasicAWSCredentials">
             <constructor-arg index="0" value="${amazon.accessKey}" />
             <constructor-arg index="1" value="${amazon.secretKey}" />
        </bean>
    
        <bean id="amazonDynamoDBClient" class="com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient">
            <constructor-arg index="0" ref="BasicAWSCredentials" />
            <property name="endpoint" value="http://dynamodb.us-west-2.amazonaws.com" />
        </bean>
    
        <bean id="dynamoDBMapper" class="com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper">
            <constructor-arg index="0" ref="amazonDynamoDBClient" />
            <constructor-arg index="1" ref="dynamoDBMapperConfig" />
        </bean>
    
    </beans>
    

    说明:

    考虑到我的 AccessKey 对象指向 AWS DynamodDB 上的 APP-ACCESSKEY 表,结果证明在运行此之后,您的应用程序将开始指向 DES-APP-ACCESSKEY。

    希望它对面临类似情况的人有所帮助

    干杯

    【讨论】:

    • 我使用了相同的配置,但tableNameOverride 为空,tableNamePrefix 具有表的名称,它给出了错误:{table} not annotated with @DynamoDBTable
    • 几个问题,1.假设使用dynamodb:repositories base-package,我们需要添加dynamodb-mapper-config-ref=??连同 amazon-dynamodb-ref
    • @shivarajan 我不明白问题出在哪里。为了让您获得灵活的 tableNamePrefix 的优势,您需要引用 DynamoDBMapper 类,该类需要 DynamoDBMapperConfig 和 AmazonDynamoDBClient 引用。这就是 SDK 的定义方式。
    【解决方案2】:

    withTableNamePrefix 是一个静态方法。所以这一行是用字符串“test”创建TableNameOverride 的一个新实例,然后通过调用静态withTableNamePrefix 方法来丢弃该实例:

    TableNameOverride tbl = new TableNameOverride("test").withTableNamePrefix("dev_");
    

    要回答将测试与生产分开的更深层次的问题,我建议完全拥有 2 个单独的 AWS 账户,一个用于开发,一个用于生产。这是您可以做到的唯一方法:

    • 单独查看帐单
    • 确保您绝不在产品和测试系统之间泄露数据
    • 开发表的高扩展性会阻止您将产品表扩展得更高

    【讨论】:

    • 回复:“我建议完全拥有 2 个单独的 AWS 账户,一个用于开发,一个用于生产”:我非常同意,但是使用“dev_”和“prod_”前缀,以便任何手动操作(例如通过 AWS 控制台)在视觉上很明显您正在操作哪一个。 (人类很容易忘记他们正在使用哪个 AWS 帐户......)
    【解决方案3】:

    与 Paolo Almeidas 解决方案相同,但带有 Spring-Boot 注释。 只是想分享它,也许可以节省一些时间:

    我有每个命名空间的 dynamodb 表,例如myApp-dev-UserTable、myApp-prod-UserTable 和我正在使用 EKS_NAMESPACE 环境变量,在我的例子中,它由 kubernetes 注入到 pod 中。

    import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
    import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
    import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
    import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
    
    @Configuration
    @EnableDynamoDBRepositories(basePackages = "de.dynamodb")
    public class DynamoDBConfig {
    
        @Value("${EKS_NAMESPACE}")
        String eksNamespace;
    
        @Bean
        public AmazonDynamoDB amazonDynamoDB() {
            return AmazonDynamoDBClientBuilder.standard()
                .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
                        "dynamodb.eu-central-1.amazonaws.com", "eu-central-1"))
                .withCredentials(awsCredentials())
                .build();
        }
    
        @Bean
        public AWSCredentialsProvider awsCredentials() {
            return WebIdentityTokenCredentialsProvider.builder().build();
        }
    
        // Table Name override:
    
        @Bean
        public DynamoDBMapperConfig.TableNameOverride tableNameOverride() {
            return DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix("myApp-" + eksNamespace + "-");
        }
    
        @Bean
        public DynamoDBMapperConfig dynamoDBMapperConfig() {
            return DynamoDBMapperConfig.builder().withTableNameOverride(tableNameOverride()).build();
        }
    
        @Bean
        // Marked as primary bean to override default bean.
        @Primary
        public DynamoDBMapper dynamoDBMapper() {
            return new DynamoDBMapper(amazonDynamoDB(), dynamoDBMapperConfig());
        }
    }
    

    这样的表格:

    @Data
    @DynamoDBTable(tableName = "UserTable")
    public class User {
    
            @DynamoDBHashKey
            private String userId;
    
            @DynamoDBAttribute
            private String foo;
    
            @DynamoDBAttribute
            private String bar;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-04
      • 2015-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      相关资源
      最近更新 更多