根据我的代码,首先,我向地图添加新字典,然后将其成功更新到我的地图。但是,当我向地图添加另一个字典时,地图中的现有键就会被覆盖。
def update_item(table_name, id, new_company):
table = dynamodb.Table(table_name)
result = table.update_item(
Key={
'id': id
},
UpdateExpression="SET company = :company",
ExpressionAttributeValues={
':company': new_company
},
ReturnValues="ALL_NEW"
)
print(result)
if __name__ == '__main__':
company_1 = {
"Facebook" : {
"CEO" : "Mark"
}
}
update_item('companies', 1, company_1)
company_2 = {
"Twitter": {
"CEO": "Jack"
}
}
update_item('companies', 1, company_2)
我的输出:我的Dynamodb表中可用的项目
{
'company': {
'Twitter': {
'CEO': 'Jack'
}
},
'id': Decimal('1'),
'industry': 'industry'
}
预期输出:
{
'company': {
'Facebook': {
'CEO': 'Mark'
}
'Twitter': {
'CEO': 'Jack'
}
},
'id': Decimal('1'),
'industry': 'industry'
}
当我向地图添加新字典时,如何避免覆盖现有字典?我是DynamoDB的新手,任何建议都将对您有所帮助。
答案 0 :(得分:2)
问题出在您的UpdateExpression
上。您每次将company
映射的值设置为新值:
SET company = :company
但是听起来您想将新值追加到company
映射中。
this post中的答案应该有助于您指出正确的方向。
答案 1 :(得分:1)
您只需要在#name上添加一个地图条目即可。
def update_item(table_name, id, new_company):
table = dynamodb.Table(table_name)
name = list(new_company)[0]
result = table.update_item(
Key={
'id': id
},
UpdateExpression="SET company.#name = :company",
ExpressionAttributeNames={"#name": name},
ExpressionAttributeValues={
':company': new_company[name]
},
ReturnValues="ALL_NEW"
)
print(result)
输出:我的Dynamodb中可用的项目
{
'company': {
'Facebook': {
'CEO': 'Mark'
},
'Twitter': {
'CEO': 'Jack'
}
},
'id': Decimal('1'),
'industry': 'internet'
}
答案 2 :(得分:1)
我是 Lucid-Dynamodb 的作者,它是 AWS DynamoDB 的极简包装器。使用我的库可以轻松解决此问题。
参考: https://github.com/dineshsonachalam/Lucid-Dynamodb
from LucidDynamodb.Operations import DynamoDb
import os
import logging
logging.basicConfig(level=logging.INFO)
AWS_ACCESS_KEY_ID = os.getenv("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.getenv("AWS_SECRET_ACCESS_KEY")
table_schema = {
"TableName": "company",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "N"
}
],
"GlobalSecondaryIndexes": [],
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
}
if __name__ == "__main__":
# 1. create a new table
db = DynamoDb(region_name="us-east-1",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
table_creation_status = db.create_table(
TableName=table_schema.get("TableName"),
KeySchema=table_schema.get("KeySchema"),
AttributeDefinitions=table_schema.get("AttributeDefinitions"),
GlobalSecondaryIndexes=table_schema.get("GlobalSecondaryIndexes"),
ProvisionedThroughput=table_schema.get("ProvisionedThroughput")
)
if(table_creation_status == True):
logging.info("{} table created successfully".format(table_schema.get("TableName")))
else:
logging.error("{} table creation failed".format(table_schema.get("TableName")))
# 2. Create a new item
item_creation_status = db.create_item(
TableName=table_schema.get("TableName"),
Item= {
'company': {
'Facebook': {
'CEO': 'Mark'
}
},
'id': 1,
'industry': 'internet'
}
)
if(item_creation_status == True):
logging.info("Item created successfully")
else:
logging.warning("Item creation failed")
# 3. Add a new attribute in a item
item_update_status = db.update_item(
TableName=table_schema.get("TableName"),
Key={
'id': 1
},
AttributesToUpdate={
'company.Twitter': {
'CEO': 'Jack'
}
}
)
if(item_update_status == True):
logging.info("Update is successful")
else:
logging.warning("Update failed")
item = db.read_item(
TableName=table_schema.get("TableName"),
Key={
'id': 1
})
if(item != None):
logging.info("Item: {}".format(item))
else:
logging.warning("Item doesn't exist")
dineshsonachalam@macbook Dynamodb-experiment % python test.py
INFO:root:company table created successfully
INFO:root:Item created successfully
INFO:root:Update is successful
INFO:root:Item:
{
'company': {
'Facebook': {
'CEO': 'Mark'
},
'Twitter': {
'CEO': 'Jack'
}
},
'id': Decimal('1'),
'industry': 'internet'
}