为什么我的代码没有在表中放置任何内容?

时间:2019-02-14 06:59:53

标签: node.js amazon-web-services aws-lambda amazon-dynamodb

我试图从S3中存储的csv文件导入数据,并将数据放入DynamaDB表中。在node.js中的Lambda函数中,一切正常,我的数据很好导出。

我试图查看我的Item是否有问题,因此我将var params放在函数的开头(在s3.getObjet之前),并将数据放入了dynamoDB表中。 另外,我试图查看我的问题是否是我的if,但是在if中,console.log不能正常工作。 我认为,唯一的问题是我的代码,而且我认为这是范围问题?

var AWS = require("aws-sdk"),
    documentClient = new AWS.DynamoDB.DocumentClient(); 
var s3 = new AWS.S3();

exports.handler = function(event, context, callback) {
    var src_bkt = event.Records[0].s3.bucket.name;
    var src_key = event.Records[0].s3.object.key;
    var file;
    var lignea;

    // Retrieve the object
    s3.getObject({
        Bucket: src_bkt,
        Key: src_key
    }, function(err, dataFile) {
        if (err) {
            console.log(err, err.stack);
            callback(err);
        } else {
            file = dataFile.Body.toString('ascii');
            var rows = file.split('\n');
            for(var i in rows){
                lignea = rows[i].split(';');
                if(lignea[2].startsWith('/France/Toulouse/')){
                    console.log("hey");
                    var params = {
                        Item : {
                            "ASSETTAG" : 'c',
                            "MAINHOST" : 'c'
                        },
                            TableName : process.env.TABLE_NAME
                        };
                        documentClient.put(params, function(err, data){
                            callback(err, data);
                    });
                }
            }
        }
    });
};

编辑:在帮助下,我的异步代码如下:

var AWS = require("aws-sdk"),
    documentClient = new AWS.DynamoDB.DocumentClient(); 
var s3 = new AWS.S3();

exports.handler = async function(event, context, callback) {
    var src_bkt = event.Records[0].s3.bucket.name;
    var src_key = event.Records[0].s3.object.key;
    var file;
    var lignea;
    try{
    // Retrieve the object
    const dataFile = s3.getObject({
        Bucket: src_bkt,
        Key: src_key
    }).promise();

    file = dataFile.Body.toString('ascii');
    var rows = file.split('\n');
        for(var i in rows){
        lignea = rows[i].split(';');
                if(lignea[2].startsWith('/France/Toulouse/')){
            console.log("hey");
            var params = {
                Item : {
                    "ASSETTAG" : 'test1',
                    "MAINHOST" : 'test2'
                },
                    TableName : process.env.TABLE_NAME
                };
                await documentClient.put(params).promise();  
        }
    }
    }catch(e){
        console.error("FAIL");
    }
};

谢谢您的帮助!

3 个答案:

答案 0 :(得分:1)

实际上,当第一个放置结果出现时,您实际上是在调用处理程序的回调,该结果将导致过程的立即结束。

尝试以下更改:

exports.handler = async function

这将启用处理异步代码的异步/等待机制。

await documentClient.put(params).promise();

几乎所有的AWS方法都有此变体,它返回Promise而不是使用回调。 await语法以同步方式等待Promise结果。

const dataFile = await s3.getObject({
        Bucket: src_bkt,
        Key: src_key
    }).promise();

删除所有回调。

将整个处理程序关闭到try/catch块中。

答案 1 :(得分:0)

您是对的,这是一个范围问题,因为您正在for循环中调用异步函数。我相信您可以这样重写它:

function putDocument (params) {
    return function() { documentClient.put(params, callback) };
}

for(var i in rows){
    lignea = rows[i].split(';');
    if(lignea[2].startsWith('/France/Toulouse/')){
        console.log("hey");
        var params = {
            Item : {
                "ASSETTAG" : 'c',
                "MAINHOST" : 'c'
            },
            TableName : process.env.TABLE_NAME
        };
        putDocument(params);
    }
}

您也可以在定义let时尝试使用params,因为它将具有正确的作用域,或使用.forEach创建闭包。

答案 2 :(得分:0)

我注意到两件事

  • 您正在循环调用回调,每一行每一行
  • 您正在调用具有相同参数的put

您应该使用“异步”之类的软件包

var AWS = require("aws-sdk"),
	documentClient = new AWS.DynamoDB.DocumentClient(); 
var s3 = new AWS.S3();
var async = require("async")

exports.handler = function(event, context, callback) {
	var src_bkt = event.Records[0].s3.bucket.name;
	var src_key = event.Records[0].s3.object.key;
	var file;
	var lignea;
	
	// Retrieve the object
	s3.getObject({
		Bucket: src_bkt,
		Key: src_key
	}, function(err, dataFile) {
		if (err) {
			console.log(err, err.stack);
			return callback(err);
		} 

		var things_to_insert = []

		file = dataFile.Body.toString('ascii');
		var rows = file.split('\n');
		for(var i in rows){
			lignea = rows[i].split(';');
			if(lignea[2].startsWith('/France/Toulouse/')){
				console.log("hey");
				var params = {
					Item : {
						"ASSETTAG" : lignea[0], // this must be your partition key
						"MAINHOST" : lignea[1]  // this must be your sort key
					},
					TableName : process.env.TABLE_NAME
				};
				things_to_insert.push(params)
			}
		}

		async.forEachOf(things_to_insert, function(params, key, cb ) {
			documentClient.put(params, function(err, data){
				cb(err, data);
			});
		}, function(err) {
			callback(err) // called only once at the end 
		})
	});
};