将json文件加载到DynamoDB中

时间:2018-02-15 16:55:04

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

当我使用本地文件使用Node执行它时,这个javaScript代码很有用,但现在当我在命令行运行它时,我得到“Undefined:1”。

var AWS = require('aws-sdk');
const http = require("http");

AWS.config.update({ region: "us-east-1" });

//cron(0 18 ? * MON-FRI *)
var docClient = new AWS.DynamoDB.DocumentClient();

console.log("Importing Work Orders into DynamoDB Jobs table. Please wait.");

http.get('http://www.MyWebSite.com/Data/WOjson/02152018.json', (res) => {
  const { statusCode } = res;
  const contentType = res.headers['content-type'];

  let error;
  if (statusCode !== 200) {
    error = new Error('Request Failed.\n' +
                      `Status Code: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error('Invalid content-type.\n' +
                      `Expected application/json but received ${contentType}`);
  }
  if (error) {
    console.error(error.message);
    // consume response data to free up memory
    res.resume();
    return;
  }

console.log("Now it is time to parse the file.");

  res.setEncoding('utf8');
  let rawData = '';

res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
  });
const parsedData = JSON.parse(rawData);

parsedData.forEach(function(job) {
    var params = {
        TableName: "Jobs",
        Item: {
            "userId":  job.userId,
            "WorkOrder": job.WorkOrder,
            "ServiceDate":  job.ServiceDate,
            "JobType": job.JobType
        }
    };

// Here is where I post to the DynamoDB table
    docClient.put(params, function(err, data) {
       if (err) {
           console.error("Unable to add job", job.WorkOrder, ". Error JSON:", JSON.stringify(err, null, 2));
       } else {
           console.log("PutItem succeeded:", job.WorkOrder);
       }
    });
});


}).on('error', (e) => {
  console.error(`Got error: ${e.message}`);
});

我已经更新了代码以使用http。我确实收到了控制台日志消息,“现在是时候解析文件了。”但是后来我收到消息“Undefined:1”并且没有任何项目进入我的DynamoDB表。

res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
  });
const parsedData = JSON.parse(rawData);

parsedData.forEach(function(job) {

理想情况下,我想按计划(每天一次,比如说下午6点)执行这个lambda函数,将远程文件读入我的DynamoDB表。

1 个答案:

答案 0 :(得分:0)

我没有使用fs API那么多,但我认为它不适合您的用例,因为我认为它涉及本地(相对于服务器)文件系统而不是远程。从理论上讲,AWS可以访问我认为短暂的/tmp文件夹,因此我认为它不是存储数据的好地方。 对于您的用例,我有两种方法可以考虑处理相同的事情:

  1. 捆绑一个处理http请求的模块(例如请求模块),然后您可以使用该模块与远程文件进行交互,当它在Lambda上时,基本上它会像:
  2. if(process.env.USE_REMOTE_FS) {
      const request = require('request');
      // use request module
      // async/await or turn to a promise
      request.get('http://www.MyWebSite.com/Data/WOjson/02152018.json',...)
      ...
    } else {
      const fs = require('fs');
      // use fs module
      ...
    }
    
    1. 捆绑一个处理细节的模块。在Ruby中,有一个open-uri Gem,我认为节点open-uri存在类似的东西,它可以根据传入的uri做类似的事情。 这就像:
    2. const open = require('open-uri');
      // you can async/await or turn this to a promise
      open(uri, function(err, jsonData) { JSON.parse(jsonData) });
      

      如果您不想处理过多的功能管理和部署,也可以使用低级http模块而不是请求模块。

      更新1

      我刚检查了fs的文档,看起来readFileSync应该有效,但是你应该提供一个URL对象,所以基本上我想象你首先创建你的URL并将其传递给FS。就个人而言,我更喜欢open-uri选项,因为它抽象了很多这些细节。

      更新2

      const http = require('http');
      
      http.get('http://www.MyWebSite.com/Data/WOjson/02152018.json', (res) => {
        // deal with your status code etc here
        ...
      
        let data = '';
      
        res.on('data', (chunk) => {
          data += chunk; // append chunk to data
        });
      
        resp.on('end', () => {
          // this is where the rest of your code could be called. there are several approaches to calling here, either abstracting the remaining work to a function and pass in the data or wrapping the http call with a promise etc. For now, let's log the data
          const parsedData = JSON.parse(data)
          console.log( parsedData );
          ...
          parsedData.forEach(...)
        });
      
      }).on("error", (err) => {
        console.log("Error occured: " + err.message);
      });