web-dev-qa-db-ja.com

boto3を使用してdynamodbのアイテムのいくつかの属性を更新する方法

私は、dynamoDBのテーブルから1つのアイテムのいくつかの属性を更新しようとしています。私のコードはPython 3.にあります。3。試すたびに、更新式とその記述方法に関連するいくつかのエラーが発生します。AWSサイトのドキュメントと例を確認しましたが、 AttributeUpdatesに関連する1つのステップで混乱しています。

これは、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'
    }
  ]
});_

更新する変数は、文字列と文字列のリストの2種類です。

_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"
_

それで私はアマゾンで例をチェックして、それの構造に従いました:

_        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"

                )
_

AttributeUpdatesのすべての変数で次のエラーが発生しました。

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

したがって、私は 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"

                )
_

そして、次のエラーが発生しました:

_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
_

もう一度ドキュメントを確認しましたが、アクションをどこに配置するか、どちらを使用するかについて混乱しました。

注:文字列リストを文字列セットに変更するか、それらを1つの文字列に結合して、どの種類のものがわからないので物事を簡略化できますpythonオブジェクトは、Node.jsで定義されているJoi.array().allow(null)オブジェクトと互換性があります。

8
Julian Abril

何度か試して 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
                    }
            )

注:これはメソッドがアイテムを再書き込みするため、アイテムからすべての属性を再度渡すことを忘れないでください。そうしないと、属性が上書きされ、消される。

編集:

コードの問題は、ExpressionAttributeValuesの代わりにAttributeUpdateを使用していたことでした。これを変更し、 'url'をキーとして(urlは予約されたWordであるため)、正常に機能するコードで使用しました。

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"

        )
4
Julian Abril