DynamoDB 映射器有条件保存新行更新失败
DynamoDB mapper conditional save failing for new row updates
假设我在 DDB 中有以下 table。一个哈希键(我们称之为 'Name'),一个范围键(我们称之为 'Activity')和一个属性(我们称之为 'Date')
|---------------------|------------------|------------------|
| HashKey(S) | RangeKey(S) | Date(S) |
|---------------------|------------------|------------------|
| Sam | Fishing | 2019 |
|---------------------|------------------|------------------|
| Sam | Kayaking | 2019 |
|---------------------|------------------|------------------|
| Peter | Kayaking | 2019 |
|---------------------|------------------|------------------|
我想对此进行有条件的保存,这样我就想添加一个新的 "name + activity" 并在数据库中保持最新的日期。所以这两种可能性的细分是
1)如果已经存在基于我传入保存的哈希+范围键,我想检查我的条件表达式,如果失败则不更新。
2)如果它是一个新的散列+范围键,我想创建一个新行,而不是检查我的条件表达式(因为table中没有要检查的值)
我尝试过的例子
public void methodToDoSave() {
final Map<String, ExpectedAttributeValue> expectedAttributes =
getExpectedAttributes(date);
final DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression()
.withExpected(expectedAttributes);
mapper.save(dbItem, saveExpression);
}
private Map<String, ExpectedAttributeValue> getExpectedAttributes(
final Date date){
final Map expectedAttributeSetupForConditionalUpdate = new HashMap();
expectedAttributeSetupForConditionalUpdate
.put("Date",new ExpectedAttributeValue(new AttributeValue().withS(date))
.withComparisonOperator(ComparisonOperator.LE));
return expectedAttributeSetupForConditionalUpdate;
}
当 hash+range 键已经在 table 中时,这适用于条件检查和 success/pass,但是如果我提供一个新的范围键,条件检查似乎总是失败。
条件检查的堆栈跟踪对于向我解释问题没有多大用处,但我的假设是即使对全新的行创建也应用了条件检查,因此它失败了。
有没有办法在一次保存操作中让它工作,或者我需要先阅读,检查是否存在,如果存在则不进行条件检查而保存,如果不进行条件检查则进行保存?
我能够利用上面 Tawan 的提示并做类似的事情。
final Map expectedAttributeSetupForConditionalUpdate = new HashMap();
expectedAttributeSetupForConditionalUpdate
.put("name", new ExpectedAttributeValue().withExists(false));
expectedAttributeSetupForConditionalUpdate
.put("activity", new ExpectedAttributeValue().withExists(false));
expectedAttributeSetupForConditionalUpdate
.put("Date", new ExpectedAttributeValue(new AttributeValue().withS(date))
.withComparisonOperator(ComparisonOperator.LE));
final DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression() .withExpected(expectedAttributeSetupForConditionalUpdate)
.withConditionalOperator(ConditionalOperator.OR);
我无法使用较新的条件表达式,因为 DynamoDB 映射器在我使用的版本中尚不支持它们。本质上,此 "passes" 行不存在时的条件检查,但在行存在时使用日期。
假设我在 DDB 中有以下 table。一个哈希键(我们称之为 'Name'),一个范围键(我们称之为 'Activity')和一个属性(我们称之为 'Date')
|---------------------|------------------|------------------|
| HashKey(S) | RangeKey(S) | Date(S) |
|---------------------|------------------|------------------|
| Sam | Fishing | 2019 |
|---------------------|------------------|------------------|
| Sam | Kayaking | 2019 |
|---------------------|------------------|------------------|
| Peter | Kayaking | 2019 |
|---------------------|------------------|------------------|
我想对此进行有条件的保存,这样我就想添加一个新的 "name + activity" 并在数据库中保持最新的日期。所以这两种可能性的细分是
1)如果已经存在基于我传入保存的哈希+范围键,我想检查我的条件表达式,如果失败则不更新。
2)如果它是一个新的散列+范围键,我想创建一个新行,而不是检查我的条件表达式(因为table中没有要检查的值)
我尝试过的例子
public void methodToDoSave() {
final Map<String, ExpectedAttributeValue> expectedAttributes =
getExpectedAttributes(date);
final DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression()
.withExpected(expectedAttributes);
mapper.save(dbItem, saveExpression);
}
private Map<String, ExpectedAttributeValue> getExpectedAttributes(
final Date date){
final Map expectedAttributeSetupForConditionalUpdate = new HashMap();
expectedAttributeSetupForConditionalUpdate
.put("Date",new ExpectedAttributeValue(new AttributeValue().withS(date))
.withComparisonOperator(ComparisonOperator.LE));
return expectedAttributeSetupForConditionalUpdate;
}
当 hash+range 键已经在 table 中时,这适用于条件检查和 success/pass,但是如果我提供一个新的范围键,条件检查似乎总是失败。
条件检查的堆栈跟踪对于向我解释问题没有多大用处,但我的假设是即使对全新的行创建也应用了条件检查,因此它失败了。
有没有办法在一次保存操作中让它工作,或者我需要先阅读,检查是否存在,如果存在则不进行条件检查而保存,如果不进行条件检查则进行保存?
我能够利用上面 Tawan 的提示并做类似的事情。
final Map expectedAttributeSetupForConditionalUpdate = new HashMap();
expectedAttributeSetupForConditionalUpdate
.put("name", new ExpectedAttributeValue().withExists(false));
expectedAttributeSetupForConditionalUpdate
.put("activity", new ExpectedAttributeValue().withExists(false));
expectedAttributeSetupForConditionalUpdate
.put("Date", new ExpectedAttributeValue(new AttributeValue().withS(date))
.withComparisonOperator(ComparisonOperator.LE));
final DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression() .withExpected(expectedAttributeSetupForConditionalUpdate)
.withConditionalOperator(ConditionalOperator.OR);
我无法使用较新的条件表达式,因为 DynamoDB 映射器在我使用的版本中尚不支持它们。本质上,此 "passes" 行不存在时的条件检查,但在行存在时使用日期。