DynamoDB 中条件写入的日期时间比较 [英] DateTime Comparison for Conditional Writes in 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屋!