Home > Software design >  How to get this list of dict in DynamoDB using boto3?
How to get this list of dict in DynamoDB using boto3?

Time:12-03

This is an example of items I want to add in DynamoDB:

Item 1:

user :{'Id': '123456789', 'Name': 'user2', 'Keys': [{'KeyId': '987654321', 'keyStatus': 'Active'}]}

Item 2:

user :{'Id': '59940303', 'Name': 'user2', 'Keys': [{'KeyId': '987654321', 'keyStatus': 'Active'},{'KeyId': '6382920434', 'keyStatus': 'Active'}]}

As you can see the Keys section contains a list of dicts. Item1 contains one dict, item2 contains two dicts.

How can I add this in DynamoDB?

This works (without the list of dicts):

table = dynamodb_resource.Table("name")
table.update_item(
    TableName=table_name,
    Key={"Id": user["Id"]},
    UpdateExpression="set Name=:n",
    ExpressionAttributeValues={
        ":n": user["Name"]
    },
    ReturnValues="UPDATED_NEW"

But How should I update this for a list of dicts?

CodePudding user response:

Updates work fine for me as follows:

table.update_item(
    Key={"id": user["Id"]},
    UpdateExpression="set #n=:n, #k=:k",
    ExpressionAttributeValues={":n": user["Name"], ":k": user["Keys"]},
    ExpressionAttributeNames={"#n": "Name", "#k": "Keys"},
    ReturnValues="UPDATED_NEW",
)

CodePudding user response:

Here's a working example:

from boto3.dynamodb.conditions import Key

users = [
  {"Id": "A123456789", "Name": "user1", "Keys": [{"KeyId": "A987654321", "keyStatus": "Active"}],},
  { "Id": "B123456789", "Name": "user2", "Keys": [{"KeyId": "Z987654321", "keyStatus": "Active"},{"KeyId": "C6382920434", "keyStatus": "Active"},],},
]

# create the two records
for user in users:
  tbl.update_item(
      Key={
          "Id": user["Id"],
      },
      UpdateExpression="set #name=:n, #keys=:k",
      ExpressionAttributeValues={
          ":n": user["Name"],
          ":k": user["Keys"],
      },
      ExpressionAttributeNames={"#name": "Name", "#keys": "Keys"},  # fields are reserved keywords! we must use substitution
      ReturnValues="UPDATED_NEW",
  )

# query a record
res = tbl.query(KeyConditionExpression=Key('Id').eq('B123456789'))
print(res["Items"][0])
# {'Id': 'B123456789', 'Keys': [{'keyStatus': 'Active', 'KeyId': 'Z987654321'}, {'keyStatus': 'Active', 'KeyId': 'C6382920434'}],}


# update a nested attribute - set the first key status to inactive
tbl.update_item(
    Key={"Id": "B123456789"},
    UpdateExpression="set #keys[0].#status=:s",
    ExpressionAttributeValues={
        ":s":  "Inactive",
    },
    ExpressionAttributeNames={"#keys": "Keys", "#status": "keyStatus"},
    ReturnValues="UPDATED_NEW",
)

# query the updated record again
res = tbl.query(KeyConditionExpression=Key('Id').eq('B123456789'))
print(res["Items"][0])
# {'Id': 'B123456789', 'Keys': [{'KeyId': 'Z987654321', 'keyStatus': 'Inactive'}, {'keyStatus': 'Active', 'KeyId': 'C6382920434'}], 'Name': 'user2'}
  • Related