Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon web services DynamoDB:UpdateItem,忽略ExpressionAttributeValue中的空值_Amazon Web Services_Lambda_Amazon Dynamodb_Aws Lambda - Fatal编程技术网

Amazon web services DynamoDB:UpdateItem,忽略ExpressionAttributeValue中的空值

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 = :

我正在使用DynamoDB更新数据库中的记录。像这样的基本功能对我来说很有用

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。只是一个说明,
属性更新
现在是一个很好的方法,我们鼓励你使用它<代码>更新表达式。