web-dev-qa-db-fra.com

Exemple de update_item dans dynamodb boto3

Après la documentation , je tente de créer une instruction de mise à jour qui ajoutera ou ajoutera s’il n’existe pas un seul attribut dans une table dynamodb.

J'essaye ça

response = table.update_item(
    Key={'ReleaseNumber': '1.0.179'},
    UpdateExpression='SET',
    ConditionExpression='Attr(\'ReleaseNumber\').eq(\'1.0.179\')',
    ExpressionAttributeNames={'attr1': 'val1'},
    ExpressionAttributeValues={'val1': 'false'}
)

L'erreur que je reçois est:

botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the UpdateItem operation: ExpressionAttributeNames contains invalid key: Syntax error; key: "attr1"

Si quelqu'un a fait quelque chose de similaire à ce que j'essaie de réaliser, partagez un exemple.

14
Dmitry R

Exemple de travail trouvé ici , très important de lister en tant que clés tous les index de la table, cela nécessitera une requête supplémentaire avant la mise à jour, mais cela fonctionne.

response = table.update_item(
    Key={
        'ReleaseNumber': releaseNumber,
        'Timestamp': result[0]['Timestamp']
    },
    UpdateExpression="set Sanity = :r",
    ExpressionAttributeValues={
        ':r': 'false',
    },
    ReturnValues="UPDATED_NEW"
)
31
Dmitry R

Les détails sur les mises à jour de dynamodb à l'aide de boto3 semblent incroyablement rares en ligne. J'espère donc que ces solutions alternatives sont utiles.

obtenir/mettre

import boto3

table = boto3.resource('dynamodb').Table('my_table')

# get item
response = table.get_item(Key={'pkey': 'asdf12345'})
item = response['Item']

# update
item['status'] = 'complete'

# put (idempotent)
table.put_item(Item=item)

mise à jour réelle

import boto3

table = boto3.resource('dynamodb').Table('my_table')

table.update_item(
    Key={'pkey': 'asdf12345'},
    AttributeUpdates={
        'status': 'complete',
    },
)
4
Ryan Tuck

L'exemple de code original:

response = table.update_item(
    Key={'ReleaseNumber': '1.0.179'},
    UpdateExpression='SET',
    ConditionExpression='Attr(\'ReleaseNumber\').eq(\'1.0.179\')',
    ExpressionAttributeNames={'attr1': 'val1'},
    ExpressionAttributeValues={'val1': 'false'}
)

Fixé:

response = table.update_item(
    Key={'ReleaseNumber': '1.0.179'},
    UpdateExpression='SET #attr1 = :val1',
    ConditionExpression=Attr('ReleaseNumber').eq('1.0.179'),
    ExpressionAttributeNames={'#attr1': 'val1'},
    ExpressionAttributeValues={':val1': 'false'}
)

Dans la réponse marquée, il a également été révélé qu’il existe une clé de plage qui devrait également être incluse dans Key. La méthode update_item doit rechercher l'enregistrement exact à mettre à jour, il n'y a pas de mises à jour par lot et vous ne pouvez pas mettre à jour une plage de valeurs filtrée sur une condition pour obtenir un enregistrement unique. La ConditionExpression est là pour être utile pour rendre les mises à jour idempotentes; c'est-à-dire ne met pas à jour la valeur s'il s'agit déjà de cette valeur . Ce n'est pas comme une clause sql where.

En ce qui concerne l'erreur spécifique vue. 

ExpressionAttributeNames est une liste d'espaces réservés de clés à utiliser dans UpdateExpression, utile si la clé est un mot réservé. 

Dans la documentation, "Un nom d'attribut d'expression doit commencer par un # et être suivi d'un ou de plusieurs caractères alphanumériques". L'erreur est due au fait que le code n'a pas utilisé un ExpressionAttributeName qui commence par un # et ne l'a pas non plus utilisé dans la UpdateExpression.

ExpressionAttributeValues sont des espaces réservés pour les valeurs que vous souhaitez mettre à jour, et ils doivent commencer par :

1
Davos