web-dev-qa-db-fra.com

Comment mettre à jour plusieurs attributs d'un article dans dynamodb en utilisant boto3

J'essaie de mettre à jour plusieurs attributs d'un élément d'une table dans dynamoDB. Mon code est en Python 3. Chaque fois que j'essaie, plusieurs erreurs sont associées à l'expression de mise à jour et à son écriture. J'ai vérifié la documentation et les exemples sur le site AWS, mais je me suis trompé à une étape liée à AttributeUpdates.

Ceci est l'index de la table qui a été créée dans Node.js (je ne peux le modifier d'aucune façon):

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'
    }
  ]
});

Mes variables à mettre à jour sont de deux types, chaînes et liste de chaînes:

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"

J'ai donc vérifié l'exemple sur Amazon et en ai suivi la structure:

        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"

                )

J'ai eu l'erreur suivante pour toutes les variables dans AttributeUpdates:

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

J'ai donc suivi la documentation AWS boto3 et remplacé les variables par des dictionnaires dans lesquels le code du type de variable est la clé et la variable est la valeur.

        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"

                )

Et j'ai eu l'erreur suivante:

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

Une fois de plus, j’ai vérifié la documentation, mais j’ai eu du mal à savoir où placer l’action et laquelle utiliser.

Note: Je peux changer la liste de chaînes en un jeu de chaînes ou les joindre en une seule chaîne pour simplifier les choses, car je ne sais pas vraiment quel type d'objets python sont compatibles avec l'objet Joi.array().allow(null) défini dans Node.js.

5
Julian Abril

Après plusieurs tentatives et lecture de la documentation de l'API Dynamodb i, nous avons constaté que la méthode PutItem:

Crée un nouvel élément ou remplace un ancien article par un nouvel article. Si un élément ayant la même clé primaire que le nouvel élément existe déjà dans la table spécifiée, le nouvel élément remplace complètement l'élément existant.

Cela peut ne pas être optimal, mais en utilisant putItem avec les mêmes clés et valeurs, l’élément entier peut être remplacé, dans ce cas, 

        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
                    }
            )

note: N'oubliez pas de repasser tous les attributs de l'élément, car cette méthode va réécrire l'élément, sinon ils seront écrasés et effacés.

Modifier:

Le problème avec le code était que j'utilisais AttributeUpdate au lieu de ExpressionAttributeValues, une fois que je l'ai changé et "url" en tant que clé (car url est un mot réservé) dans le code, il fonctionne normalement

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"

        )
1
Julian Abril