将 list_append 与 DynamoDB 中的地图列表一起使用
Using list_append with list of maps in DynamoDB
我有一个 DynamoDB table,其架构类似于以下内容。我基本上想在 jobs
属性上 运行 一个 "upsert" 函数,它将添加作业属性或追加到列表中。
执行我的代码时,我收到一条错误消息:
An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: list_append, operand type: M
架构:
{
"jobs": [
{
"event_id": "event_id",
"job_map": [
{
"key1": "val1",
"key2": "val2"
}
],
"job_start": "time_stamp"
}
],
"p_key": "some_id"
}
Example/documentation:
示例代码:
p_key_string = 'some_id'
event_id = '123'
job_start = 'timestamp_string'
task_map = []
for item in items:
task_map.append({
"M": {
'key1': {"S": item.get('val1')},
'key2': {"S": item.get('val2')}
}
})
args = {
'Key': {
'p_key': p_key_string
},
'UpdateExpression': "SET p_key = :p_key, #ri = list_append(#ri, :vals)",
'ConditionExpression': "attribute_not_exists(p_key) OR p_key = :p_key",
'ExpressionAttributeNames': {
"#ri": "jobs"
},
'ExpressionAttributeValues': {
':p_key': p_key_string,
':vals': {
"L": [{
"M": {
"event_id": { "S": event_id},
"job_start": { "S": job_start},
'job_map': { "L": task_map}
}
}]
}
}
}
dynamo_client.update_item(**args)
根据错误,我尝试了一个更简单的查询,但实际上得到了同样的错误。
...
':vals': {
"L": [
{ "S": event_id},
{ "S": job_start}
]
}
...
所以真的不确定我错过了什么。
我不太确定我理解原因,但通过删除数据类型声明,我能够克服错误。上面的代码还有一些其他错误,但下面的更改似乎对我有用。
...
task_map.append({
'key1': 'val1',
'key2': 'val2'
})
...
...
args = {
'Key': {
'p_key': p_key_string
},
'UpdateExpression': "SET jobs = list_append(if_not_exists(jobs, :empty_list), :vals)",
'ExpressionAttributeValues': {
':vals': [{
"event_id": event_id,
"job_start": job_start,
"job_map": task_map
}],
":empty_list": []
}
}
...
dynamodb_client
实际上是一个 Table
对象而不是常规的 dynamodb 客户端吗?
Table
对象会自动将 dynamodb 数据格式转换为本机数据类型,而常规 DynamoDB 客户端不会。
如果您使用的是文档客户端,则不需要使用类型操作数。你可以用原生 JS 编写对象。我 运行 遇到了类似的问题,并按照@getglad 的建议删除了类型声明并且交易有效。
我有一个 DynamoDB table,其架构类似于以下内容。我基本上想在 jobs
属性上 运行 一个 "upsert" 函数,它将添加作业属性或追加到列表中。
执行我的代码时,我收到一条错误消息:
An error occurred (ValidationException) when calling the UpdateItem operation: Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: list_append, operand type: M
架构:
{
"jobs": [
{
"event_id": "event_id",
"job_map": [
{
"key1": "val1",
"key2": "val2"
}
],
"job_start": "time_stamp"
}
],
"p_key": "some_id"
}
Example/documentation:
示例代码:
p_key_string = 'some_id'
event_id = '123'
job_start = 'timestamp_string'
task_map = []
for item in items:
task_map.append({
"M": {
'key1': {"S": item.get('val1')},
'key2': {"S": item.get('val2')}
}
})
args = {
'Key': {
'p_key': p_key_string
},
'UpdateExpression': "SET p_key = :p_key, #ri = list_append(#ri, :vals)",
'ConditionExpression': "attribute_not_exists(p_key) OR p_key = :p_key",
'ExpressionAttributeNames': {
"#ri": "jobs"
},
'ExpressionAttributeValues': {
':p_key': p_key_string,
':vals': {
"L": [{
"M": {
"event_id": { "S": event_id},
"job_start": { "S": job_start},
'job_map': { "L": task_map}
}
}]
}
}
}
dynamo_client.update_item(**args)
根据错误,我尝试了一个更简单的查询,但实际上得到了同样的错误。
...
':vals': {
"L": [
{ "S": event_id},
{ "S": job_start}
]
}
...
所以真的不确定我错过了什么。
我不太确定我理解原因,但通过删除数据类型声明,我能够克服错误。上面的代码还有一些其他错误,但下面的更改似乎对我有用。
...
task_map.append({
'key1': 'val1',
'key2': 'val2'
})
...
...
args = {
'Key': {
'p_key': p_key_string
},
'UpdateExpression': "SET jobs = list_append(if_not_exists(jobs, :empty_list), :vals)",
'ExpressionAttributeValues': {
':vals': [{
"event_id": event_id,
"job_start": job_start,
"job_map": task_map
}],
":empty_list": []
}
}
...
dynamodb_client
实际上是一个 Table
对象而不是常规的 dynamodb 客户端吗?
Table
对象会自动将 dynamodb 数据格式转换为本机数据类型,而常规 DynamoDB 客户端不会。
如果您使用的是文档客户端,则不需要使用类型操作数。你可以用原生 JS 编写对象。我 运行 遇到了类似的问题,并按照@getglad 的建议删除了类型声明并且交易有效。