我试图从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");
}
};
谢谢您的帮助!
答案 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)
我注意到两件事
您应该使用“异步”之类的软件包
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
})
});
};