web-dev-qa-db-fra.com

Comment ajouter une valeur à un attribut de liste sur AWS DynamoDB?

J'utilise DynamoDB comme base de données K-V (car il n'y a pas beaucoup de données, je pense que ça va), et une partie de 'V' est de type liste (environ 10 éléments). Il y a une session pour y ajouter une nouvelle valeur, et je ne peux pas trouver un moyen de le faire dans 1 demande. Ce que j'ai fait est comme ceci:

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

Je demande d'abord le serveur et l'enregistre après avoir modifié la valeur. Ce n'est pas atomique et ça a l'air moche. Existe-t-il un moyen de le faire en une seule demande?

18
kxxoling

Le code suivant devrait fonctionner avec 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']

La méthode get_dynamodb_resource ici est juste:

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

Vous pouvez le faire dans 1 demande en utilisant l'API UpdateItem conjointement avec un UpdateExpression . Puisque vous voulez ajouter à une liste, vous utiliseriez l'action SET avec la fonction list_append:

SET prend en charge les fonctions suivantes:

...

  • list_append (operand, operand) - évalue une liste avec un nouvel élément ajouté. Vous pouvez ajouter le nouvel élément au début ou à la fin de la liste en inversant l'ordre des opérandes.

Vous pouvez voir quelques exemples de cela sur la Modification des éléments et des attributs avec la documentation des expressions de mise à jour :

  • L'exemple suivant ajoute un nouvel élément à la liste de révision FiveStar . Le nom de l'attribut d'expression #pr Est ProductReviews ; la valeur d'attribut :r est une liste à un élément. Si la liste avait précédemment deux éléments, [0] Et [1], Alors le nouvel élément sera [2].

    SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
    
  • L'exemple suivant ajoute un autre élément à la liste de révision FiveStar , mais cette fois l'élément sera ajouté au début de la liste à [0]. Tous les autres éléments de la liste seront décalés d'un.

    SET #pr.FiveStar = list_append(:r, #pr.FiveStar)
    

#pr Et :r Utilisent des espaces réservés pour les noms et les valeurs d'attribut. Vous pouvez voir plus d'informations sur celles-ci dans la documentation tilisation des espaces réservés pour les noms et valeurs d'attribut .

7
mkobit

Je regarderais les expressions de mise à jour: http://docs.aws.Amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html#Expressions.Modifying.UpdateExpressions.ADD

Devrait être faisable avec un ADD, bien que vous ne sachiez pas quel est le support de boto pour cela.

1
Mircea