Почему мой код ничего не помещает в мою таблицу? - PullRequest
0 голосов
/ 14 февраля 2019

Я попытался импортировать данные из CSV-файла, хранящегося в S3, и поместить данные в таблицу DynamaDB.В моей функции Lambda, которая находится в node.js, все работает нормально, мои данные хорошо экспортируются.

Я попытался выяснить, не было ли это проблемы с моим Item, поэтому я поместил параметры var в началефункция (до 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 голосов
/ 14 февраля 2019

Вы на самом деле вызываете функцию обратного вызова обработчика, когда приходит первый результат пут, который приводит к немедленному завершению процесса.

Попробуйте эти изменения:

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.

0 голосов
/ 14 февраля 2019

Я заметил две вещи

  • вы вызываете обратный вызов в цикле, для каждой строки для каждой строки
  • вы звоните, положить с теми же параметрами

вы должны использовать пакет типа "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 
		})
	});
};
0 голосов
/ 14 февраля 2019

Вы правы, это проблема объема, потому что вы вызываете асинхронную функцию внутри цикла 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 для создания замыкания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...