Dmi*_*y R 25 python amazon-dynamodb botocore boto3
在文档之后,我正在尝试创建一个更新或添加的更新语句,如果在dynamodb表中只存在一个属性.
我正在尝试这个
response = table.update_item(
Key={'ReleaseNumber': '1.0.179'},
UpdateExpression='SET',
ConditionExpression='Attr(\'ReleaseNumber\').eq(\'1.0.179\')',
ExpressionAttributeNames={'attr1': 'val1'},
ExpressionAttributeValues={'val1': 'false'}
)
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the UpdateItem operation: ExpressionAttributeNames contains invalid key: Syntax error; key: "attr1"
如果有人做了类似于我想要实现的任何事情,请分享示例.
Dmi*_*y R 35
在这里找到工作示例,非常重要的是列出表的所有索引,这将在更新之前需要额外的查询,但它的工作原理.
response = table.update_item(
Key={
'ReleaseNumber': releaseNumber,
'Timestamp': result[0]['Timestamp']
},
UpdateExpression="set Sanity = :r",
ExpressionAttributeValues={
':r': 'false',
},
ReturnValues="UPDATED_NEW"
)
Run Code Online (Sandbox Code Playgroud)
Jam*_*eno 14
如果您不想逐个参数检查更新,我编写了一个很酷的函数,该函数将返回使用 boto3执行update_item方法所需的参数。
def get_update_params(body):
"""Given a dictionary we generate an update expression and a dict of values
to update a dynamodb table.
Params:
body (dict): Parameters to use for formatting.
Returns:
update expression, dict of values.
"""
update_expression = ["set "]
update_values = dict()
for key, val in body.items():
update_expression.append(f" {key} = :{key},")
update_values[f":{key}"] = val
return "".join(update_expression)[:-1], update_values
Run Code Online (Sandbox Code Playgroud)
这是一个快速示例:
def update(body):
a, v = get_update_params(body)
response = table.update_item(
Key={'uuid':str(uuid)},
UpdateExpression=a,
ExpressionAttributeValues=dict(v)
)
return response
Run Code Online (Sandbox Code Playgroud)
Rya*_*uck 13
使用boto3网上动态稀疏的有关dynamodb更新的详细信息,因此我希望这些替代解决方案有用。
import boto3
table = boto3.resource('dynamodb').Table('my_table')
# get item
response = table.get_item(Key={'pkey': 'asdf12345'})
item = response['Item']
# update
item['status'] = 'complete'
# put (idempotent)
table.put_item(Item=item)
Run Code Online (Sandbox Code Playgroud)
import boto3
table = boto3.resource('dynamodb').Table('my_table')
table.update_item(
Key={'pkey': 'asdf12345'},
AttributeUpdates={
'status': 'complete',
},
)
Run Code Online (Sandbox Code Playgroud)
原始代码示例:
response = table.update_item(
Key={'ReleaseNumber': '1.0.179'},
UpdateExpression='SET',
ConditionExpression='Attr(\'ReleaseNumber\').eq(\'1.0.179\')',
ExpressionAttributeNames={'attr1': 'val1'},
ExpressionAttributeValues={'val1': 'false'}
)
Run Code Online (Sandbox Code Playgroud)
固定:
response = table.update_item(
Key={'ReleaseNumber': '1.0.179'},
UpdateExpression='SET #attr1 = :val1',
ConditionExpression=Attr('ReleaseNumber').eq('1.0.179'),
ExpressionAttributeNames={'#attr1': 'val1'},
ExpressionAttributeValues={':val1': 'false'}
)
Run Code Online (Sandbox Code Playgroud)
在标记的答案中,还显示有一个范围键,因此也应将其包含在Key。update_item方法必须查找要更新的确切记录,没有批处理更新,并且您不能将经过过滤的值范围更新为获取单个记录的条件。的ConditionExpression是那里是有益的,使更新幂等; 也就是说,如果已经是该值,则不要更新该值。它不像sql where子句。
关于看到的具体错误。
ExpressionAttributeNames 是要在UpdateExpression中使用的键占位符的列表,如果键是保留字,则很有用。
在文档中,“表达式属性名称必须以#开头,后跟一个或多个字母数字字符”。错误是因为代码未使用以a开头的ExpressionAttributeName,#也未在中使用它UpdateExpression。
ExpressionAttributeValues 是您要更新的值的占位符,并且必须以 :
基于官方示例,这里有一个简单而完整的解决方案,可用于手动更新(不是我推荐的)terraform S3 后端使用的表。
假设这是 AWS CLI 显示的表数据:
$ aws dynamodb scan --table-name terraform_lock --region us-east-1
{
"Items": [
{
"Digest": {
"S": "2f58b12ae16dfb5b037560a217ebd752"
},
"LockID": {
"S": "tf-aws.tfstate-md5"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
Run Code Online (Sandbox Code Playgroud)
您可以将其更新为新的摘要(假设您回滚了状态),如下所示:
$ aws dynamodb scan --table-name terraform_lock --region us-east-1
{
"Items": [
{
"Digest": {
"S": "2f58b12ae16dfb5b037560a217ebd752"
},
"LockID": {
"S": "tf-aws.tfstate-md5"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
Run Code Online (Sandbox Code Playgroud)
请注意它们:开头的":newDigest": "50a488ee9bac09a50340c02b33beb24b"很容易错过或忘记。