将 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:

  1. Running upsert functions on Dynamo
  2. Appending to Dynamo lists

示例代码:

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 的建议删除了类型声明并且交易有效。