将list_append与DynamoDB中的地图列表一起使用

时间:2019-09-18 12:51:47

标签: amazon-dynamodb dynamodb-queries

我有一个DynamoDB表,其架构类似于以下内容。我实际上想在jobs属性上运行“ upsert”函数,该函数将添加jobs属性或追加到列表中。

执行代码时,我收到一条错误消息:

  

调用UpdateItem操作时发生错误(ValidationException):无效的UpdateExpression:运算符或函数的操作数类型错误;运算符或函数:list_append,操作数类型:M

模式:

{
  "jobs": [
    {
      "event_id": "event_id",
      "job_map": [
        {
          "key1": "val1",
          "key2": "val2"
        }
      ],
      "job_start": "time_stamp"
    }
  ],
  "p_key": "some_id"
}

示例/文档:

  1. Running upsert functions on Dynamo
  2. Appending to Dynamo lists
  3. SO question with answers I am pretty sure I'm following

示例代码:

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}
    ]
}
...

所以真的不确定我缺少什么。

3 个答案:

答案 0 :(得分:0)

我不确定我为什么会这样,但是通过删除数据类型声明,我能够克服错误。上面的代码还有一些其他错误,但是下面的更改似乎对我有用。

...
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": []
  }
}
...

答案 1 :(得分:0)

dynamodb_client实际上是Table对象,而不是常规的dynamodb客户程序吗?

Table对象将自动将dynamodb数据格式转换为本机数据类型,而常规DynamoDB客户端则不会。

答案 2 :(得分:0)

如果您使用的是文档客户端,则不需要使用类型操作数。您可以在本机 JS 中编写对象。我遇到了类似的问题,并按照 @getglad 的建议删除了类型声明并且事务正常工作。

相关问题