1

I have a DynamoDB table with a schema similar to the below. I want to essentially run an "upsert" function on the jobs attribute that will either add the jobs attribute or append to the list.

When executing my code, I am getting an error message:

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

Schema:

{
  "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
  3. SO question with answers I am pretty sure I'm following

Sample code:

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)

Based on the error I tried a simpler query, but actually got the same error.

...
':vals': {
    "L": [
        { "S": event_id},
        { "S": job_start}
    ]
}
...

So really not sure what I am missing.

3 Answers 3

1

I'm not entirely sure I understand why, but by removing the data type declarations, I was able to move past the error. The code above had some additional errors, but the below changes appear to be working for me.

...
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": []
  }
}
...
Sign up to request clarification or add additional context in comments.

Comments

0

Is dynamodb_client actually a Table object and not the regular dynamodb client?

The Table object will automatically convert the dynamodb data format into native data types while the regular DynamoDB client does not.

Comments

0

If you are using the Document Client then you don't need to use type operands. You can write the objects in native JS. I was running into a similar issue and followed @getglad's advice to remove the type declarations and the transactions worked.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.