如果项目不存在,请插入DynamoDB

时间:2019-10-08 16:59:26

标签: node.js aws-lambda amazon-dynamodb amazon-rekognition

我正在使用aws-rekognition对流视频进行出勤检查,当识别出一个人时,lambda应该将其写入DynamoDB。 insertDynamo()可以单独正常工作(当我不将其称为函数时),但是当我将其放在函数中时,它不会写入DynamoDB表。知道做错什么了吗?

var AWS = require('aws-sdk');
var today = new Date();
var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();
var hour = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();

exports.handler = async (event, context) => {
    //console.log('Received event:', JSON.stringify(event, null, 2));


    event.Records.forEach((record) => {

            // Kinesis data is base64 encoded so decode here
            const load = new Buffer(record.kinesis.data, 'base64').toString('ascii');
            const payload = JSON.parse(load);
           if(payload.FaceSearchResponse != null)
           {
               payload.FaceSearchResponse.forEach((face) =>  {

                   if(face.MatchedFaces != null && 
                         Object.keys(face.MatchedFaces).length > 0)
                   {
                       var id = JSON.stringify(face.MatchedFaces[0].Face.ExternalImageId, null, 4);
                       //this is hard code it ---needs to split string from kinesis(id)
                       insertDynamo(date,hour,'0001');
                   }
                   else
                   {
                       //do nothing
                   }
               });
           }
        });
    return `Successfully processed ${event.Records.length} records.`;
};

var insertDynamo = function(date,hour,id){
    exports.handler = async (event,context) => {
    const documentClient = new AWS.DynamoDB.DocumentClient();
    let responseBody = "";
    let statusCode = 0;

    const params = {
        TableName: "users",
        Item:{
            badgeNumber: id,
            assistance:{
                date:date,
                hour:hour
            }
        },
        ConditionExpression: 'attribute_not_exists(badgenumber)'    
    };

    try {
        const data = await documentClient.put(params).promise();
        responseBody = JSON.stringify(data);
        statusCode = 201;
    } catch (err) {
        responseBody = `Unable to put product: ${err}`;
        statusCode = 403;
    }    

    const response = {
        statusCode: statusCode,
        headers: {
            "Content-Type": "application/json"
        },
        body:responseBody
    }
    return response
}
};

1 个答案:

答案 0 :(得分:0)

您的lambda函数将在调用后立即完成,因为您使用.forEach遍历了所有记录。这意味着您所有插入DynamoDB的请求都将在它们完成yobs之前被取消。

针对您的情况,我有2种解决方案:

  1. 等待,直到清除lambda回调堆栈

    只需在您的lambda函数之前添加一个“ config”行

       context.callbackWaitsForEmptyEventLoop = true;
    
  2. 使用旧式循环代替forEach(推荐)。 forEach使用回调样式来解决每个项目,因此无法像我们期望的那样使用async/await关键字。

var AWS = require('aws-sdk');
var today = new Date();
var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
var hour = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();

exports.handler = async (event, context) => {
  //console.log('Received event:', JSON.stringify(event, null, 2));

  for (const record of event.Records) { // for of instead of forEach
    const load = new Buffer(record.kinesis.data, 'base64').toString('ascii');
    const payload = JSON.parse(load);
    if (payload.FaceSearchResponse != null) {
      for (const face of payload.FaceSearchResponse) { // for of instead of forEach
        if (face.MatchedFaces != null &&
          Object.keys(face.MatchedFaces).length > 0) {
          var id = JSON.stringify(face.MatchedFaces[0].Face.ExternalImageId, null, 4);
          //this is hard code it ---needs to split string from kinesis(id)
          await insertDynamo(date, hour, '0001'); // wait until task finish then solve next item
        }
        else {
          //do nothing
        }
      }
    }
  }
  return `Successfully processed ${event.Records.length} records.`;
};

var insertDynamo = function (date, hour, id) {
  // What is this?????????
  // exports.handler = async (event, context) => {

  // }

  const documentClient = new AWS.DynamoDB.DocumentClient();

  const params = {
    TableName: "users",
    Item: {
      badgeNumber: id,
      assistance: {
        date: date,
        hour: hour
      }
    },
    ConditionExpression: 'attribute_not_exists(badgenumber)'
  };

  return documentClient.put(params).promise(); // enough for us
};