Amazon web services DynamoDB:UpdateItem,忽略ExpressionAttributeValue中的空值
我正在使用DynamoDB更新数据库中的记录。像这样的基本功能对我来说很有用Amazon web services DynamoDB:UpdateItem,忽略ExpressionAttributeValue中的空值,amazon-web-services,lambda,amazon-dynamodb,aws-lambda,Amazon Web Services,Lambda,Amazon Dynamodb,Aws Lambda,我正在使用DynamoDB更新数据库中的记录。像这样的基本功能对我来说很有用 var user = { userID: '123213', name: 'John Doe', age: 12, type: 'creator' }; var params = { TableName:table, Key:{ "UserID": user.userID }, UpdateExpression: "set Name = :
var user = {
userID: '123213',
name: 'John Doe',
age: 12,
type: 'creator'
};
var params = {
TableName:table,
Key:{
"UserID": user.userID
},
UpdateExpression: "set Name = :r, Age=:p, Type=:a",
ExpressionAttributeValues:{
":r":user.name,
":p":user.age,
":a":user.type
},
ReturnValues:"UPDATED_NEW"
};
docClient.update(params, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));
}
});
但是…
如果我只想更新一个属性,名称,如下所示:
var user = {
userID: '123213',
name: 'John Smith'
};
var params = {
TableName:table,
Key:{
"UserID": user.userID
},
UpdateExpression: "set Name = :r, Age=:p, Type=:a",
ExpressionAttributeValues:{
":r":user.name,
":p":user.age,
":a":user.type
},
ReturnValues:"UPDATED_NEW"
};
for (var key in user) {
if (user.hasOwnProperty(key)) {
...add to DynamicUpdateExpression..
}
}
这给了我一个错误
表达式属性值不能为NULL
我知道我可以通过检查user中的值动态生成UpdateExpression
字符串,如下所示:
var user = {
userID: '123213',
name: 'John Smith'
};
var params = {
TableName:table,
Key:{
"UserID": user.userID
},
UpdateExpression: "set Name = :r, Age=:p, Type=:a",
ExpressionAttributeValues:{
":r":user.name,
":p":user.age,
":a":user.type
},
ReturnValues:"UPDATED_NEW"
};
for (var key in user) {
if (user.hasOwnProperty(key)) {
...add to DynamicUpdateExpression..
}
}
但是有没有一种方法可以让updateItem忽略空值,只更新
名称
?我问了同样的问题…在Java中有,但我在aws sdk中找不到类似的nodejs
您可以使用AttributeUpdates而不是UpdateExpression来创建更清晰的解决方案:
const AWS = require(aws-sdk);
const bluebird = require('bluebird');
const _ = require('lodash');
AWS.config.setPromisesDependency(bluebird);
const dynamodb = new AWS.DynamoDB.DocumentClient();
var skipNullAttributes = (attributes) => {
return _.omitBy(attributes, (attr) => {
return _.isNil(attr.Value);
});
}
var update = (id, attributes) => {
var params = {
TableName : 'MyTableName',
Key : { id: id },
AttributeUpdates: skipNullAttributes(attributes)
};
return dynamodb.update(params).promise();
}
exports.handler = (event, context, callback) => {
var body = JSON.parse(event.body);
var userId = event.pathParameters.id;
var attributes = {
firstName: { Action: 'PUT', Value: body.firstName },
lastName : { Action: 'PUT', Value: body.lastName }
};
update(userId, attributes)
.then((result) => console.log(result) )
.catch((error) => console.error(error) );
callback(null, {statusCode: 200, body: JSON.stringify({message: 'done!'})});
}
这是一个简单得多的答案
当你考虑一个对象的表达式属性值时,它是有效的。
代码如下:params.TableName = ddbTable;
params.UpdateExpression = "set LastPostedDateTime = :l" ;
if (req.body.AttachmentDescription) { params.UpdateExpression += ", AttachmentDescription = :d"; }
if (req.body.AttachmentURL) { params.UpdateExpression += ", AttachmentURL = :a"; }
因此,首先,我们使用一种简单的连接技术,建立表达式(如果可以传递值)
然后,我们提供以下值:
params.ExpressionAttributeValues = {};
params.ExpressionAttributeValues[':l'] = formattedDate ;
if (req.body.AttachmentDescription) { params.ExpressionAttributeValues[':d']= req.body.AttachmentDescription ; }
if (req.body.AttachmentURL) { params.ExpressionAttributeValues[':a']= req.body.AttachmentURL ; }
难点在于ExpressionAttributeValues,在这里,我们将其视为一个对象,如果我们首先将其定义为一个对象,那么我们可以将其添加到对象中,因此{}
然后,如果对象尚未具有属性名称,则将其添加,然后添加值
最终的结果是您可以拥有非常宽的平面记录,因为您的记录可以使用变量字段名进行扩展。也就是说,此应用程序列出了URL和描述符。使用变量字段名,我可以向同一记录添加更多URL和描述符。最终会有一个内存限制,但是这种类型的应用程序(对于一些变量字段)对于我的应用程序来说就足够了。我通过向我的
documentClient
构造函数传递一个附加选项,获得了所需的结果
const documentClient = new AWS.DynamoDB.DocumentClient({convertEmptyValues: true});
这会将空字符串转换为
true
(在dynamodb world中也称为NULL
),并且我的http请求json对象中缺少的字段不会影响数据库或导致请求失败。我发现了另一种方法,其灵感来源于上面@David White的答案。此外,OP非常接近于通过动态编写UpdateExpression和ExpressionAttributeValue来实现正确的操作。下面是关于如何生成动态更新表达式的代码,无论给定了什么属性
constcreate=(请求、上下文、回调)=>{
const data=JSON.parse(req.body)
常量参数={
表名:process.env.DYNAMODB_表,
键:{title:data.title},
};
params.UpdateExpression=“SET latestUpdate=:updateTime”
params.ExpressionAttributeValues={}
for(让k输入数据){
如果(k!=“标题”){
//您不想更新已设置为表主键的内容,因此必须忽略此项
params.UpdateExpression+=`,${k}=:${k}`
params.ExpressionAttributeValues[`:${k}`]=数据[k]
}
}
params.ExpressionAttributeValues[':updateTime']=Date.now()
dynamodb.update(参数)
这是一个很好的建议。谢谢。我只想再等一天,看看是否有人找到了方法,如果没有,我将排除这个答案。你找到了关于它的任何信息吗?我什么都找不到。我什么也没找到。我将接受tit。只是一个说明,属性更新
现在是一个很好的方法,我们鼓励你使用它<代码>更新表达式。