web-dev-qa-db-ja.com

AWS DynamoDBのリスト属性に値を追加する方法は?

私はDynamoDBをK-V dbとして使用しています(データがあまりないため、それでいいと思います)。また、「V」の一部はリストタイプ(約10要素)です。新しい値を追加するセッションがあり、1回のリクエストでこれを行う方法が見つかりません。私がしたことはこのようなものです:

item = self.list_table.get_item(**{'k': 'some_key'})
item['v'].append('some_value')
item.partial_save()

最初にサーバーを要求し、値を変更した後に保存します。それはアトミックではなく、looksいように見えます。 1つのリクエストでこれを行う方法はありますか?

18
kxxoling

次のコードはboto3で動作するはずです。

table = get_dynamodb_resource().Table("table_name")
result = table.update_item(
    Key={
        'hash_key': hash_key,
        'range_key': range_key
    },
    UpdateExpression="SET some_attr = list_append(some_attr, :i)",
    ExpressionAttributeValues={
        ':i': [some_value],
    },
    ReturnValues="UPDATED_NEW"
)
if result['ResponseMetadata']['HTTPStatusCode'] == 200 and 'Attributes' in result:
    return result['Attributes']['some_attr']

ここのget_dynamodb_resourceメソッドは次のとおりです。

def get_dynamodb_resource():
    return boto3.resource(
            'dynamodb',
            region_name=os.environ['AWS_DYNAMO_REGION'],
            endpoint_url=os.environ['AWS_DYNAMO_ENDPOINT'],
            aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
            aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'])
41
LaserJesus

UpdateItem APIを UpdateExpression と組み合わせて使用​​すると、1回のリクエストでこれを実行できます。リストに追加したいので、SETアクションを_list_append_関数と共に使用します:

SETは次の機能をサポートします。

...

  • list_append (operand, operand)-新しい要素が追加されたリストを評価します。オペランドの順序を逆にすることにより、リストの先頭または末尾に新しい要素を追加できます。

更新式を使用したアイテムと属性の変更ドキュメント で、このいくつかの例を見ることができます:

  • 次の例では、FiveStarレビューリストに新しい要素を追加します。式属性名_#pr_はProductReviews;属性値_:r_は1要素のリストです。リストに以前に_[0]_と_[1]_の2つの要素があった場合、新しい要素は_[2]_になります。

    _SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
    _
  • 次の例では、別の要素をFiveStarレビューリストに追加しますが、今回は要素がリストの先頭の_[0]_に追加されます。リスト内の他の要素はすべて1ずつシフトされます。

    _SET #pr.FiveStar = list_append(:r, #pr.FiveStar)
    _

_#pr_と_:r_は、属性名と値にプレースホルダーを使用しています。これらの詳細については、 属性名と値のプレースホルダーの使用に関するドキュメント をご覧ください。

7
mkobit

更新式を見ます: http://docs.aws.Amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html#Expressions.Modifying.UpdateExpressions.ADD

ADDで実行可能である必要がありますが、botoでのサポートがこれに対して何であるかはわかりません。

1
Mircea