DynamoDB 中条件写入的日期时间比较 [英] DateTime Comparison for Conditional Writes in DynamoDB

查看:30
本文介绍了DynamoDB 中条件写入的日期时间比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 DynamoDB.如果该记录的日期早于新记录日期字段,我想使用条件写入来更新该记录.

I'm working with DynamoDB at the moment. I want to use a conditional write to update a record if that record has a date that is older than the new record date field.

有没有办法比较条件写入的 DateTime 类型?还是目前仅适用于整数、字符串和流?

Is there a way to compare DateTime types for conditional writes? Or is it currently only for integers, strings and streams?

谢谢.

推荐答案

既然你提到你正在使用 ISO-8601 使用 String 数据类型,很容易使用比较运算符(<<= 等)在您的条件表达式中,因为在这个答案.

Since you mentioned you are using ISO-8601 with the String datatype, it is easy to use the comparing operators (<, <=, etc.) in your conditional expression because of the lexicographical ordering described in this answer.

以下是我使用 Java 8 的时间并在 DynamoDB Local 上运行的快速示例:

Here is a quick example where I used Java 8's time and ran it against DynamoDB Local:

import com.google.common.collect.ImmutableMap;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import com.amazonaws.services.dynamodbv2.util.Tables;

import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class DynamoDBStackoverflow {

    public static final String TABLE_NAME = "exampleTable";
    private static final String HASH_KEY = "hashAttributeName";

    public static void main(String[] args) {

        AWSCredentials awsCredentials = new BasicAWSCredentials("key", "secret");
        AmazonDynamoDB client = new AmazonDynamoDBClient(awsCredentials);
        client.setEndpoint("http://localhost:4000");
        DynamoDB dynamoDB = new DynamoDB(client);

        if (Tables.doesTableExist(client, TABLE_NAME)) {
            client.deleteTable(TABLE_NAME);
        }

        final CreateTableRequest createTableRequest = new CreateTableRequest()
            .withTableName(TABLE_NAME)
            .withKeySchema(new KeySchemaElement(HASH_KEY, KeyType.HASH))
            .withAttributeDefinitions(new AttributeDefinition(HASH_KEY, ScalarAttributeType.S))
            .withProvisionedThroughput(new ProvisionedThroughput(15L, 15L));
        final Table table = dynamoDB.createTable(createTableRequest);

        final Instant now = Instant.now();
        final Instant before = now.minus(10, ChronoUnit.MINUTES).truncatedTo(ChronoUnit.MINUTES);
        final Instant after = now.plus(10, ChronoUnit.MINUTES);
        System.out.println("Before: " + before.toString());
        System.out.println("Now: " + now.toString());
        System.out.println("After: " + after.toString());

        table.putItem(new Item().withPrimaryKey(HASH_KEY, "1")
                          .withString("dateField", before.toString()));
        table.putItem(new Item().withPrimaryKey(HASH_KEY, "2")
                          .withString("dateField", now.toString()));
        System.out.println("put items");
        table.scan().forEach(System.out::println);

        UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey(HASH_KEY, "1")
            .withConditionExpression("dateField < :beforeDate")
            .withValueMap(ImmutableMap.of(":beforeDate", before.toString()))
            .withUpdateExpression("SET dateField = :beforeDate");

        try {
            table.updateItem(updateItemSpec);
            throw new RuntimeException();
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("expected conditional write with < to fail when they are equal");
        }

        updateItemSpec = new UpdateItemSpec().withPrimaryKey(HASH_KEY, "2")
            .withConditionExpression("dateField < :beforeDate")
            .withValueMap(ImmutableMap.of(":beforeDate", before.toString()))
            .withUpdateExpression("SET dateField = :beforeDate");

        try {
            table.updateItem(updateItemSpec);
            throw new RuntimeException();
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("expected conditional write with < to fail when new is before");
        }

        updateItemSpec = new UpdateItemSpec().withPrimaryKey(HASH_KEY, "1")
            .withConditionExpression("dateField <= :beforeDate")
            .withValueMap(ImmutableMap.of(":beforeDate", before.toString()))
            .withUpdateExpression("SET dateField = :beforeDate");

        try {
            table.updateItem(updateItemSpec);
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("should not happen");
            throw new RuntimeException();
        }

        updateItemSpec = new UpdateItemSpec().withPrimaryKey(HASH_KEY, "2")
            .withConditionExpression("dateField <= :afterDate")
            .withValueMap(ImmutableMap.of(":afterDate", after.toString()))
            .withUpdateExpression("SET dateField = :afterDate");
        try {
            table.updateItem(updateItemSpec);
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("should not happen");
            throw new RuntimeException();
        }

        System.out.println();
        System.out.println("after all updates");
        table.scan().forEach(System.out::println);
    }
}

和输出:

Before: 2015-06-08T15:57:00Z
Now: 2015-06-08T16:07:08.893Z
After: 2015-06-08T16:17:08.893Z
put items
{ Item: {hashAttributeName=1, dateField=2015-06-08T15:57:00Z} }
{ Item: {hashAttributeName=2, dateField=2015-06-08T16:07:08.893Z} }
expected conditional write with < to fail when they are equal
expected conditional write with < to fail when new is before

after all updates
{ Item: {hashAttributeName=1, dateField=2015-06-08T15:57:00Z} }
{ Item: {hashAttributeName=2, dateField=2015-06-08T16:17:08.893Z} }

这篇关于DynamoDB 中条件写入的日期时间比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆