【问题标题】:Why my code doesn't put anything in my table?为什么我的代码没有在我的表中放任何东西?
【发布时间】:2019-02-15 03:54:55
【问题描述】:

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

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

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");
    }
};

感谢您的帮助!

【问题讨论】:

  • 尽量使用ES6。你能检查一下你得到的表名吗?

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


【解决方案1】:

当第一个 put 结果出现时,您实际上是在调用处理程序的回调,这会导致进程立即结束。

试试这些改变:

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 块中。

【讨论】:

  • 感谢您的回答,但如果我这样做,我无法将 toString 放入我的 dataFile 变量,所以我的代码不起作用,我不熟悉异步函数,所以我觉得我做得不好
  • 在您编辑的代码中,您忘记将await 放在我写的s3.getObject 调用之前。
  • 我太笨了!非常感谢
【解决方案2】:

我注意到了两件事

  • 您正在循环中调用回调,针对每一行的每一行
  • 您使用相同的参数调用 put

你应该使用像“async”这样的包

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 
		})
	});
};

【讨论】:

    【解决方案3】:

    你是对的,这是一个范围问题,因为你在 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);
        }
    }
    

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

    【讨论】:

    • 它仍然不起作用,但你是对的问题是循环,但我不明白为什么
    • 我认为我的代码有错误,并修复了我上面的答案。我还包括了第一个闭包解决方案的一些替代方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多