更新 dynamodb 记录中的属性
update attributes in a dynamodb record
我正在尝试更新我的 dynamodb table 中的现有记录。
如下所示,我的 table
中有一个项目
let params = {
TableName: proces.env.dynamoDbTable,
Item: {
productId: "id",
att1: val1,
att2: val2
}
}
我想执行更新。我正在使用 aws dynamodb sdk 的更新方法并将其传递给如下参数
let aws = require('aws-sdk');
let dbb = new aws.DynamoDb.DocumentClient();
let params = {
TableName: process.env.tableName,
Key: {productID}
ExpressionAttributeNames: { "#updatedAt" : "updatedAt" }
ExpressionAttributeValues: {":u":moment().unix(), ":val1" : a, ":val2": b}
UpdateExpression: "SET att1 = :val1, att2: val2, #updatedAt: :u"
}
// a, b are passed as argument to function and are optional
dbb.update(params).promise()
当参数丢失时,dynamo 引发 ExpressionAttributeValue 丢失异常,我知道它是直接的。有没有一种方法可以使用提供的属性更新我的项目
不幸的是,dynamodb 并没有让这变得容易。但是你可以使用一些花哨的 js 来动态创建 params 对象:
// for some object `attrs` we find which keys we need to update
const keys = Object.keys(attrs);
const values = Object.values(attrs);
// get a list of key names and value names to match the dynamodb syntax
const attributeKeyNames = keys.map((k) => '#key_' + k);
const attributeValueNames = keys.map((k) => ':val_' + k);
// create individual expressions for each attribute that needs to be updated
const expressions = attributeValueNames.map((attr, i) => {
return `${attributeKeyNames[i]} = ${attr}`;
});
// add the SET keyword to the beginning of the string
// and join all the expressions with a comma
const UpdateExpression = 'SET ' + expressions.join(', ');
// I use `zipObject()` from lodash https://lodash.com/docs/4.17.15#zipObject
// it makes an object map from two arrays where the first is the keys and
// the second is the values
const ExpressionAttributeValues = _.zipObject(attributeValueNames, values);
const ExpressionAttributeNames = _.zipObject(attributeKeyNames, keys);
// now you have all the params
const params = {
TableName,
Key: {
uuid,
},
UpdateExpression,
ExpressionAttributeValues,
ExpressionAttributeNames,
};
效果很好。不过要记住几件事:
如果您将带有唯一键的对象发送到更新函数中,则必须在映射表达式数组之前删除该键,否则它将包含在查询中并会出现错误:
const newObject = {...originalObject}
delete newObject.unique_key
如果你不能或不想使用 Lodash,你可以使用 Object.assign 来映射你的 keys/values 数组:
const ExpressionAttributeValues = Object.assign(...attributeValueNames.map((k, i) => ({[k]: values[i]})));
const ExpressionAttributeNames = Object.assign(...attributeKeyNames.map((k, i) => ({[k]: keys[i]})));
我正在尝试更新我的 dynamodb table 中的现有记录。 如下所示,我的 table
中有一个项目let params = {
TableName: proces.env.dynamoDbTable,
Item: {
productId: "id",
att1: val1,
att2: val2
}
}
我想执行更新。我正在使用 aws dynamodb sdk 的更新方法并将其传递给如下参数
let aws = require('aws-sdk');
let dbb = new aws.DynamoDb.DocumentClient();
let params = {
TableName: process.env.tableName,
Key: {productID}
ExpressionAttributeNames: { "#updatedAt" : "updatedAt" }
ExpressionAttributeValues: {":u":moment().unix(), ":val1" : a, ":val2": b}
UpdateExpression: "SET att1 = :val1, att2: val2, #updatedAt: :u"
}
// a, b are passed as argument to function and are optional
dbb.update(params).promise()
当参数丢失时,dynamo 引发 ExpressionAttributeValue 丢失异常,我知道它是直接的。有没有一种方法可以使用提供的属性更新我的项目
不幸的是,dynamodb 并没有让这变得容易。但是你可以使用一些花哨的 js 来动态创建 params 对象:
// for some object `attrs` we find which keys we need to update
const keys = Object.keys(attrs);
const values = Object.values(attrs);
// get a list of key names and value names to match the dynamodb syntax
const attributeKeyNames = keys.map((k) => '#key_' + k);
const attributeValueNames = keys.map((k) => ':val_' + k);
// create individual expressions for each attribute that needs to be updated
const expressions = attributeValueNames.map((attr, i) => {
return `${attributeKeyNames[i]} = ${attr}`;
});
// add the SET keyword to the beginning of the string
// and join all the expressions with a comma
const UpdateExpression = 'SET ' + expressions.join(', ');
// I use `zipObject()` from lodash https://lodash.com/docs/4.17.15#zipObject
// it makes an object map from two arrays where the first is the keys and
// the second is the values
const ExpressionAttributeValues = _.zipObject(attributeValueNames, values);
const ExpressionAttributeNames = _.zipObject(attributeKeyNames, keys);
// now you have all the params
const params = {
TableName,
Key: {
uuid,
},
UpdateExpression,
ExpressionAttributeValues,
ExpressionAttributeNames,
};
如果您将带有唯一键的对象发送到更新函数中,则必须在映射表达式数组之前删除该键,否则它将包含在查询中并会出现错误:
const newObject = {...originalObject}
delete newObject.unique_key
如果你不能或不想使用 Lodash,你可以使用 Object.assign 来映射你的 keys/values 数组:
const ExpressionAttributeValues = Object.assign(...attributeValueNames.map((k, i) => ({[k]: values[i]})));
const ExpressionAttributeNames = Object.assign(...attributeKeyNames.map((k, i) => ({[k]: keys[i]})));