繁体   English   中英

更新在 dynamodb 中添加属性的项目

[英]update an item adding an attribute in dynamodb

是否无法在 dynamodb 中动态添加属性?

当我尝试-“提供的关键元素与架构不匹配”时出现此错误。

场景——

{ id : "123",
  imageName : "elephant.jpg"
}

我想在上面的数据中添加一个属性 - imagePath : "/path/to/image"。 我使用了 put_item,但它会替换旧项目(如果存在)。

我正在寻找解决方案 - If id = "123", then add imagePath attribute else add a new item to the table.

可以使用 put_item 添加属性,但它将替换现有项目。 我们如何使用 update_item 向现有数据动态添加属性? (将 imagePath 附加到给定的 json)

我应该使用 imagePath 更改表的架构,然后使用 update_item 函数吗?

我们如何使用 python 实现这一目标?

不幸的是,它不能一步完成。 但是,它可以通过两步过程来实现:-

1) 尝试有条件地插入数据,即如果键值已经存在,则不执行任何操作(即插入或更新 - 没有任何反应)

2) 如果有ConditionalCheckFailedException ,则更新该项

示例代码:-

在下面的代码中, usertable是表名。 该表的关键属性是useridscore 您需要为您的表结构相应地更改以下代码。

另外,我已经分配了键值(如“Mike”)。 您需要根据您的用例相应地更改它。

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

)

更新:-

变量id的数据类型和关键属性RequestId应该匹配。

如果不存在,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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM