Step函数中的dynamodb ConditionExpression
dynamodb ConditionExpression in Step functions
使用 aws-step-functions
我正在尝试 putItem
变成 dynamodb
。
这是 .yml
的摘录,它按预期工作。
...
AddingURLs:
Type: Map
ItemsPath: "$.vidPosts"
Parameters:
vidPostsIndex.$: "$$.Map.Item.Index"
vidPosts.$: "$$.Map.Item.Value"
Iterator:
StartAt: AddingURLIntoDynamoDB
Comment: Looping over urls and adding them into the db
States:
AddingURLIntoDynamoDB:
Type: Task
Resource: arn:aws:states:::dynamodb:putItem
ResultPath: null
Parameters:
TableName: my-table-table-name
Item:
videoID:
S.$: "$.vidPosts.[0]"
urls:
S.$: "$.vidPosts.[1]"
ConditionExpression: "attribute_not_exists(videoID)"
End: true
Next: EndStepFunctions
EndStepFunctions:
Comment: This marks the end of a step functions
Type: Succeed
但是下一次,当这个状态被调用时,如果它遇到一个已经存在的条目,因为,ConditionExpression: "attribute_not_exists(videoID)"
,它应该抛出,
{
executionArn: 'arn:aws:states:us-east-2:aaabbbccc:execution:xxxStateMachine:XXX-YYY-ZZZ',
stateMachineArn: 'arn:aws:states:us-east-2:aaabbbccc:stateMachine:xxxStateMachine',
name: '9814ce93-bc42-4f31-a742-089ea7db9ad6',
status: 'FAILED',
startDate: 2021-03-18T15:30:45.912Z,
stopDate: 2021-03-18T15:30:52.386Z,
input: '{}',
inputDetails: { included: true },
error: 'DynamoDB.ConditionalCheckFailedException',
cause: 'The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: bfd76f51-567b-439c-9a39-5a1643e75a69; Proxy: null)'
}
我的问题在 aws-step-functions
内,如何让它忽略现有条目但继续使用迭代器?
感谢任何帮助并提前致谢。
我想你在这里有几个选择。
- 不要在
putItem
上设置条件。如果数据相同,那么您可以让它用新数据覆盖数据,这不会真正改变任何东西。请记住 putItem
与 SQL INSERT
不同。它更像是一个 UPSERT
.
- 在您的步骤中添加一个
Catch
块,让它继续到与成功案例相同的地方。如果您希望 putItem
的输出中的某些内容在下一步的输入中,您可能需要先使其进入 Pass
状态。
- 在执行 get 的 put 之前添加一个步骤,然后在有条件的步骤上执行 put。如果在某些情况下您可能会在很近的范围内对同一条记录进行多次调用,那么这可能不是最佳选择,因为您可能同时点击了 get 却看不到记录,然后两者都会执行 put(在这种情况下,一个会失败)。如果您永远不会遇到这种情况,那么这就可以了。
我们只需要捕获 DynamoDB.ConditionalCheckFailedException
异常并继续前进,不抛出任何错误。
我们需要的是
"Catch": [
{
"ErrorEquals": [
"DynamoDB.ConditionalCheckFailedException"
],
"Next": "FinalStep"
}
]
这是完整的步骤函数。
{
"StartAt": "put-item",
"States": {
"put-item": {
"Next": "FinalStep",
"Catch": [
{
"ErrorEquals": [
"DynamoDB.ConditionalCheckFailedException"
],
"Next": "FinalStep"
}
],
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:putItem",
"Parameters": {
"Item": {
"pk": {
"S": "1"
},
"test": {
"S": "value"
}
},
"TableName": "test",
"ConditionExpression": "attribute_not_exists(#videoID)",
"ExpressionAttributeNames": {
"#videoID": "videoID"
}
}
},
"FinalStep": {
"Type": "Pass",
"End": true
}
}
}
Put-item 因错误而失败,但仍移至下一个任务。
{
"Error": "DynamoDB.ConditionalCheckFailedException",
"Cause": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: xxxx-xxx-xxx-xxx-xxxxx; Proxy: null)"
}
使用 aws-step-functions
我正在尝试 putItem
变成 dynamodb
。
这是 .yml
的摘录,它按预期工作。
...
AddingURLs:
Type: Map
ItemsPath: "$.vidPosts"
Parameters:
vidPostsIndex.$: "$$.Map.Item.Index"
vidPosts.$: "$$.Map.Item.Value"
Iterator:
StartAt: AddingURLIntoDynamoDB
Comment: Looping over urls and adding them into the db
States:
AddingURLIntoDynamoDB:
Type: Task
Resource: arn:aws:states:::dynamodb:putItem
ResultPath: null
Parameters:
TableName: my-table-table-name
Item:
videoID:
S.$: "$.vidPosts.[0]"
urls:
S.$: "$.vidPosts.[1]"
ConditionExpression: "attribute_not_exists(videoID)"
End: true
Next: EndStepFunctions
EndStepFunctions:
Comment: This marks the end of a step functions
Type: Succeed
但是下一次,当这个状态被调用时,如果它遇到一个已经存在的条目,因为,ConditionExpression: "attribute_not_exists(videoID)"
,它应该抛出,
{
executionArn: 'arn:aws:states:us-east-2:aaabbbccc:execution:xxxStateMachine:XXX-YYY-ZZZ',
stateMachineArn: 'arn:aws:states:us-east-2:aaabbbccc:stateMachine:xxxStateMachine',
name: '9814ce93-bc42-4f31-a742-089ea7db9ad6',
status: 'FAILED',
startDate: 2021-03-18T15:30:45.912Z,
stopDate: 2021-03-18T15:30:52.386Z,
input: '{}',
inputDetails: { included: true },
error: 'DynamoDB.ConditionalCheckFailedException',
cause: 'The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: bfd76f51-567b-439c-9a39-5a1643e75a69; Proxy: null)'
}
我的问题在 aws-step-functions
内,如何让它忽略现有条目但继续使用迭代器?
感谢任何帮助并提前致谢。
我想你在这里有几个选择。
- 不要在
putItem
上设置条件。如果数据相同,那么您可以让它用新数据覆盖数据,这不会真正改变任何东西。请记住putItem
与 SQLINSERT
不同。它更像是一个UPSERT
. - 在您的步骤中添加一个
Catch
块,让它继续到与成功案例相同的地方。如果您希望putItem
的输出中的某些内容在下一步的输入中,您可能需要先使其进入Pass
状态。 - 在执行 get 的 put 之前添加一个步骤,然后在有条件的步骤上执行 put。如果在某些情况下您可能会在很近的范围内对同一条记录进行多次调用,那么这可能不是最佳选择,因为您可能同时点击了 get 却看不到记录,然后两者都会执行 put(在这种情况下,一个会失败)。如果您永远不会遇到这种情况,那么这就可以了。
我们只需要捕获 DynamoDB.ConditionalCheckFailedException
异常并继续前进,不抛出任何错误。
我们需要的是
"Catch": [
{
"ErrorEquals": [
"DynamoDB.ConditionalCheckFailedException"
],
"Next": "FinalStep"
}
]
这是完整的步骤函数。
{
"StartAt": "put-item",
"States": {
"put-item": {
"Next": "FinalStep",
"Catch": [
{
"ErrorEquals": [
"DynamoDB.ConditionalCheckFailedException"
],
"Next": "FinalStep"
}
],
"Type": "Task",
"Resource": "arn:aws:states:::dynamodb:putItem",
"Parameters": {
"Item": {
"pk": {
"S": "1"
},
"test": {
"S": "value"
}
},
"TableName": "test",
"ConditionExpression": "attribute_not_exists(#videoID)",
"ExpressionAttributeNames": {
"#videoID": "videoID"
}
}
},
"FinalStep": {
"Type": "Pass",
"End": true
}
}
}
Put-item 因错误而失败,但仍移至下一个任务。
{
"Error": "DynamoDB.ConditionalCheckFailedException",
"Cause": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: xxxx-xxx-xxx-xxx-xxxxx; Proxy: null)"
}