• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

141
Views
DynamoDB.DocumentClient con atributos dinámicos y contador atómico

Estoy trabajando en un caso de uso en el que una actualización de dynamoDB debería:

  1. Insertar dinámicamente (actualizar si está presente, insertar si no está presente) un elemento, sin codificar los componentes del elemento.
  2. Utilice el cliente de documentos de DynamoDB para simplificar
  3. Y en la misma operación atómica, actualizar un contador simple

Empecé con un método de utilidad excelente de Daniel Barrel en https://stackoverflow.com/a/63511693/15369972 que proporciona un método de utilidad general para la actualización con valores dinámicos, pero sin el contador atómico.

Intenté agregar la capacidad del contador atómico agregando el contador y su incrementador en los objetos de parámetro después de que se cargan los valores dinámicos, pero obtengo un valor estático en el contador en la actualización en lugar de un valor que se incrementa en uno con cada llamada .

¿Dónde está esto yendo mal? Llamo a la función de actualización modificada con un nombre de tabla, un objeto javascript dinámico y una matriz que contiene el hash y la clave de ordenación:

await update(tableName, jsonObjectToStore, ['myHashKey', 'mySortKey'])

Y el método de actualización modificado que no se incrementa como me gustaría, es:

 async function update (tableName, item, idAttributeNames) { var params = { TableName: tableName, Key: {}, ExpressionAttributeValues: {}, ExpressionAttributeNames: {}, UpdateExpression: "", ReturnValues: "UPDATED_NEW" }; for (const attname of idAttributeNames) { params["Key"][attname] = item[attname]; } let prefix = "set "; let attributes = Object.keys(item); for (let i=0; i<attributes.length; i++) { let attribute = attributes[i]; if (!idAttributeNames.includes(attribute)) { params["UpdateExpression"] += prefix + "#" + attribute + " = :" + attribute; params["ExpressionAttributeValues"][":" + attribute] = item[attribute]; params["ExpressionAttributeNames"]["#" + attribute] = attribute; prefix = ", "; } } // Add the counter params["UpdateExpression"] += ", #nImports = :nImports + :incr"; console.log(params["UpdateExpression"]) console.log(params["ExpressionAttributeValues"]) params["ExpressionAttributeValues"][":incr"] = 1; params["ExpressionAttributeValues"][":nImports"] = 0; console.log(params["ExpressionAttributeValues"]) console.log(params["ExpressionAttributeNames"]) params["ExpressionAttributeNames"]["#nImports"] = 'nImports' console.log(params["ExpressionAttributeNames"]) await docClient.update return await docClient.update(params).promise(); }
almost 3 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Trabajó con AWS Support para encontrar una solución razonable. Tampoco estaban seguros de cómo hacer un contador atómico usando el cliente de documentos ddb (a diferencia del cliente de bajo nivel que tiene muchos ejemplos documentados), pero sugirieron el comando ADD, que tiene el efecto secundario de una actualización atómica en un campo numérico.

Entonces, con el ejemplo a continuación, construimos nuestra actualización dinámica a partir del objeto que se almacenará, luego agregamos la declaración ADD en la expresión de actualización ( ¡sin una coma! ) y agregamos lo que es en efecto un incremento numérico a ExpressionAttributeValues para nImports. Como este, que debería ser un ejemplo completo de lambda que funcione. Hay algunas declaraciones de console.log para mostrar lo que está sucediendo:

 const AWS = require('aws-sdk'); const docClient = new AWS.DynamoDB.DocumentClient(); async function update (tableName, item, idAttributeNames) { var params = { TableName: tableName, Key: {}, ExpressionAttributeValues: {}, ExpressionAttributeNames: {}, UpdateExpression: "", ReturnValues: "UPDATED_NEW" }; for (const attname of idAttributeNames) { params["Key"][attname] = item[attname]; } let prefix = "set "; let attributes = Object.keys(item); for (let i=0; i<attributes.length; i++) { let attribute = attributes[i]; if (!idAttributeNames.includes(attribute)) { params["UpdateExpression"] += prefix + "#" + attribute + " = :" + attribute; params["ExpressionAttributeValues"][":" + attribute] = item[attribute]; params["ExpressionAttributeNames"]["#" + attribute] = attribute; prefix = ", "; } } console.log('params before adding atomic counter is:', params) // Add the counter using the ADD syntax params["UpdateExpression"] += " ADD #nImports :nImports" params["ExpressionAttributeValues"][":nImports"] = 1; params["ExpressionAttributeNames"]["#nImports"] = 'nImports' console.log('params after adding atomic counter is:', params) try { const result = await docClient.update(params).promise(); console.log('after await, result is ', result); return result; } catch (err) { console.log('err is ', err) } }; exports.handler = async (event) => { const item = {title: 'sometitle', site_url: "www.amazon.com", key: "G"}; const body = await update('test_table', item, ['title', 'site_url']); const response = { statusCode: 200, body: JSON.stringify(body), }; return response; }
almost 3 years ago · Juan Pablo Isaza Report

0

La amable gente de AWS investigó un poco más y también señaló un error en el código inicial que, cuando se corrige, debería incrementarse según lo deseado usando el operador SET.

Básicamente, el código original no apuntó correctamente a la variable para el incremento. Entonces, una versión corregida donde agregamos la variable incrementada debería ser:

 console.log('params before adding atomic counter is:', params) // Add the counter params["UpdateExpression"] += ", #nImports = #nImports + :incr"; params["ExpressionAttributeValues"][":incr"] = 1; //params["ExpressionAttributeValues"][":nImports"] = 0; params["ExpressionAttributeNames"]["#nImports"] = 'nImports' console.log('params after adding atomic counter is:', params)``` I'm sticking with the original ADD answer because I like the differentiation it gives over the properties inserted by the SET, but both seem valid and I wanted to include the correction as well
almost 3 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error