简体   繁体   English

如何使用boto3更新dynamodb中项目的多个属性

[英]How to update several attributes of an item in dynamodb using boto3

I'm trying to update several attributes of one item from a table in dynamoDB. 我正在尝试从dynamoDB中的表更新一个项目的几个属性。 My code is in Python 3. Every time I try it I get several errors related to the update expression and the way its written. 我的代码是在Python 3中。每次我尝试它时,我会得到几个与更新表达式及其编写方式相关的错误。 I checked the documentation and the examples in the AWS site, but got confused at one step related to the AttributeUpdates. 我检查了AWS站点中的文档和示例,但在与AttributeUpdates相关的一个步骤中感到困惑。

This is the index of the table which was created in Node.js (I can't modify it in any way): 这是在Node.js中创建的表的索引(我无法以任何方式修改它):

 const Pages = dynamodb.define('Page', { hashKey : 'idPages', timestamps : true,//creates 2 string variables "createdAt" & "updatedAt" schema : { idPages : dynamodb.types.uuid(),//assigns one unique ID it is a string also url: Joi.string(), var1InTable: Joi.string(),//want to update this idSite: Joi.string(), var2InTable: Joi.array().allow(null)//want to update this }, indexes: [ { hashKey: 'idSite', rangeKey: 'url', name: 'UrlIndex', type : 'global' } ] }); 

My variables to update are of two kinds, strings and list of strings: 我要更新的变量有两种,字符串和字符串列表:

dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
tb_pages=dynamodb.Table('pages')
idPages="exampleID123"#hash key 
url="www.example.com"#range key
var1String="example string"
var2StrList=["Example","String","List"]
var3NewString="new string variable"

So I checked the example in the Amazon and followed the structure of it: 所以我检查了亚马逊中的示例,并遵循它的结构:

        response=tb_pages.update_item(
            Key={
                    'idPages':item['idPages'],
                    'url':item['url']
                    },
            UpdateExpression="SET var1InTable= :var1, var2InTable= :var2,var3InTable= :var3",
            AttributeUpdates={
                    ':var1': var1String,
                    ':var2': var2StrList,
                    ':var3': var3NewString
                    },
            ReturnValues="UPDATED_NEW"

                )

I got the following error for all the variables in AttributeUpdates: 我在AttributeUpdates中的所有变量都收到以下错误:

Invalid type for parameter AttributeUpdates.:var1, value: example string, type: <class 'str'>, valid types: <class 'dict'>

So I followed the AWS boto3 documentation and replaced the variables with dictionaries where the code for the type of the variable is the key and the variable is the value. 所以我遵循AWS boto3文档并用字典替换变量,其中变量类型的代码是键,变量是值。

        response=tb_pages.update_item(
            Key={
                    'idPages':item['idPages'],
                    'url':item['url']
                    },
            UpdateExpression="SET var1InTable= :var1, var2InTable= :var2,var3InTable= :var3",
            AttributeUpdates={
                    ':var1': {"S":var1String},
                    ':var2': {"L":var2StrList},
                    ':var3': {"S":var3NewString},
                    },
            ReturnValues="UPDATED_NEW"

                )

And got the following error: 并得到以下错误:

ParamValidationError: Parameter validation failed:
Unknown parameter in AttributeUpdates.:var1: "S", must be one of: Value, Action
Unknown parameter in AttributeUpdates.:var2: "L", must be one of: Value, Action
Unknown parameter in AttributeUpdates.:var3: "S", must be one of: Value, Action

Once again I checked the documentation but got confused on where to put the action and which one should use. 我再次检查了文档,但对于放置操作的位置以及应该使用哪个操作感到困惑。

Note: I can change the string list to a string set, or join them in one string to simplify things as I don't really know which kind of python objects are compatible with the Joi.array().allow(null) object defined in Node.js. 注意:我可以将字符串列表更改为字符串集,或者将它们连接成一个字符串以简化操作,因为我实际上并不知道哪种python对象与Joi.array().allow(null)对象定义兼容在Node.js.

After several attempts and reading the Dynamodb API documentation i found that the PutItem method : 经过几次尝试并阅读Dynamodb API文档后,我发现了PutItem方法:

Creates a new item, or replaces an old item with a new item. 创建新项目,或用新项目替换旧项目。 If an item that has the same primary key as the new item already exists in the specified table, the new item completely replaces the existing item. 如果指定表中已存在与新项目具有相同主键的项目,则新项目将完全替换现有项目。

This might not be optimal but by using putItem with the same Keys and values the entire item can be replaced, in this case 这可能不是最佳的,但是通过使用具有相同键和值的putItem,可以替换整个项目,在这种情况下

        tb_pages.put_item(
            Item={
                    'idPages':item['idPages'],#hash key
                    'url':item['url'],#range key
                    'var1InTable':var1String,
                    'var2InTable':var2StrList,
                    'var3InTable':var3NewString,
                    'otherAttributeToKeep':item['otherAttributeToKeep']#see the note
                    }
            )

note: Don't forget about passing again all the attributes from the item as this is method is going to rewrite the item, otherwise they will be overwritten and get erased. 注意:不要忘记再次传递项目中的所有属性,因为这是方法将重写项目,否则它们将被覆盖并被删除。

Edit: 编辑:

The problem with the code at was i was using AttributeUpdate instead of ExpressionAttributeValues , once i changed it and 'url' as a key (because url is a reserved word) in the code it worked normally 代码的问题是我使用的是AttributeUpdate而不是ExpressionAttributeValues,一旦我更改它并且'url'作为键(因为url是保留字)在它正常工作的代码中

response=tb_pages.update_item(
    Key={
            'idPages':item['idPages'],
            'urlz':item['urlz']
            },
    UpdateExpression="SET var1InTable= :var1, var2InTable= :var2,var3InTable= :var3",
    ExpressionAttributeValues={
            ':var1': var1String,
            ':var2': var2StrList,
            ':var3': var3NewString
            },
    ReturnValues="UPDATED_NEW"

        )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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