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

Jul*_*ril 6 python database python-3.x amazon-dynamodb boto3

我正在尝试从dynamoDB中的表更新一个项目的几个属性.我的代码是在Python 3中.每次我尝试它时,我会得到几个与更新表达式及其编写方式相关的错误.我查看了AWS站点中的文档和示例,但在与AttributeUpdates相关的一个步骤中感到困惑.

这是在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'
    }
  ]
});
Run Code Online (Sandbox Code Playgroud)

我要更新的变量有两种,字符串和字符串列表:

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"
Run Code Online (Sandbox Code Playgroud)

所以我检查了亚马逊中的示例,并遵循它的结构:

        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"

                )
Run Code Online (Sandbox Code Playgroud)

我在AttributeUpdates中的所有变量都收到以下错误:

Invalid type for parameter AttributeUpdates.:var1, value: example string, type: <class 'str'>, valid types: <class 'dict'>
Run Code Online (Sandbox Code Playgroud)

所以我遵循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"

                )
Run Code Online (Sandbox Code Playgroud)

并得到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

我再次检查了文档,但对于放置操作的位置以及应该使用哪个操作感到困惑.

注意:我可以将字符串列表更改为字符串集,或者将它们连接成一个字符串以简化操作,因为我不知道哪种python对象与Joi.array().allow(null)Node.js中定义的对象兼容.

Jul*_*ril 9

经过多次尝试并阅读Dynamodb API 文档后,我发现 PutItem 方法:

创建一个新项目,或用新项目替换旧项目。如果指定表中已存在与新项目具有相同主键的项目,则新项目将完全替换现有项目。

这可能不是最佳的,但通过使用具有相同键和值的 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
                    }
            )
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记再次传递项目的所有属性,因为这是方法将重写项目,否则它们将被覆盖并被删除。

编辑:

代码的问题是我使用的是 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"

        )
Run Code Online (Sandbox Code Playgroud)

  • @AnthonyKong是的,你可以,但不要使用逗号分隔多个更新表达式:使用双空格,如下所示: `SET var1InTable = :var1, var2InTable = :var2 ADD var3InTable :var3` (3认同)
  • 太棒了,感谢您还提供了使用 uptade 项目的方法!他们确实需要在文档中提供更多示例 (2认同)