[英]update an item adding an attribute in dynamodb
Is it not possible to add an attribute in dynamodb dynamically?是否无法在 dynamodb 中动态添加属性?
I got this error when I tried-" The provided key element does not match the schema ".当我尝试-“提供的关键元素与架构不匹配”时出现此错误。
Scenario -场景——
{ id : "123",
imageName : "elephant.jpg"
}
I want to add an attribute - imagePath : "/path/to/image" to the above data.我想在上面的数据中添加一个属性 - imagePath : "/path/to/image"。 I used put_item, but it replaces the old item if exists.
我使用了 put_item,但它会替换旧项目(如果存在)。
I am searching for the solution for - If id = "123", then add imagePath attribute else add a new item to the table.我正在寻找解决方案 - If id = "123", then add imagePath attribute else add a new item to the table.
Adding an attribute can be achieved using put_item but it will replace the existing item.可以使用 put_item 添加属性,但它将替换现有项目。 How can we dynamically add an attribute to the existing data using update_item ?
我们如何使用 update_item 向现有数据动态添加属性? (appending imagePath to the the given json)
(将 imagePath 附加到给定的 json)
Should I alter the schema of the table with imagePath and then use update_item function?我应该使用 imagePath 更改表的架构,然后使用 update_item 函数吗?
How can we achieve this using python?我们如何使用 python 实现这一目标?
Unfortunately, it can't be achieved in single step.不幸的是,它不能一步完成。 However, it can be achieved in two step process:-
但是,它可以通过两步过程来实现:-
1) Try to insert the data conditionally ie if the key value is already present don't perform any operation (ie insert or update - nothing happens) 1) 尝试有条件地插入数据,即如果键值已经存在,则不执行任何操作(即插入或更新 - 没有任何反应)
2) If there is a ConditionalCheckFailedException
, then update the item 2) 如果有
ConditionalCheckFailedException
,则更新该项
Sample code:-示例代码:-
In the below code, usertable
is the table name.在下面的代码中,
usertable
是表名。 The key attributes of the table are userid
and score
.该表的关键属性是
userid
和score
。 You need to change the below code accordingly for your table structure.您需要为您的表结构相应地更改以下代码。
Also, I have assigned the key value (as "Mike").另外,我已经分配了键值(如“Mike”)。 You need to change it accordingly for your use case.
您需要根据您的用例相应地更改它。
from __future__ import print_function # Python 2/3 compatibility
from boto.dynamodb2.exceptions import ConditionalCheckFailedException
from botocore.exceptions import ClientError
from boto3.dynamodb.conditions import Attr
import boto3
import json
import decimal
# Helper class to convert a DynamoDB item to JSON.
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
return super(DecimalEncoder, self).default(o)
dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000")
table = dynamodb.Table('usertable')
userId = "Mike"
try :
response = table.put_item(
Item={
'userid': userId,
'score' : 100,
'imagePath' : '/path/to/image'
},
ConditionExpression=Attr('userid').ne(userId)
)
print("Conditional PutItem succeeded:")
print(json.dumps(response, indent=4, cls=DecimalEncoder))
except ClientError as ce :
print("Conditional check failed:", ce)
if ce.response['Error']['Code'] == 'ConditionalCheckFailedException':
print("Key already exists")
response = table.update_item(
Key={'userid': userId, 'score' : 100},
UpdateExpression="set imagePath = :imagePathVal",
ExpressionAttributeValues={":imagePathVal" : "/path/to/image" }
)
print("Update existing item succeeded:")
print(json.dumps(response, indent=4, cls=DecimalEncoder))
else:
print("Unexpected error: %s" % e
) )
Update:-更新:-
The data type of variable id
and key attribute RequestId
should match.变量
id
的数据类型和关键属性RequestId
应该匹配。
Lastest version of update_item will handle attribute creation if does not already exists如果不存在,update_item 的最新版本将处理属性创建
import boto3
from boto3.dynamodb.conditions import Key
def query_status(asset_id, dynamodb, table):
try:
response = table.query(
ProjectionExpression="#asset_id, status_id" ,
ExpressionAttributeNames={"#asset_id": "asset_id"},
KeyConditionExpression=Key('asset_id').eq(asset_id)
)
if response['Items']:
return response['Items'][0]["status_id"]
except:
pass # if attribute does not exists, return None
def update_asset_status(asset_id, status_id, dynamodb, table):
response = table.update_item(
Key={'asset_id': asset_id},
UpdateExpression="set status_id=:r",
ExpressionAttributeValues={':r': status_id},
ReturnValues="UPDATED_NEW"
)
return response
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('assets')
asset_id='1234'
print("Current Status: ", query_status(asset_id, dynamodb, table))
new_status_id='4'
update_asset_status(asset_id, new_status_id, dynamodb, table)
print("New Status: ", query_status(id, dynamodb, table))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.