【问题标题】:Loading a json file into DynamoDB将 json 文件加载到 DynamoDB
【发布时间】:2026-01-23 03:45:01
【问题描述】:

当我使用本地文件通过 Node 执行此 JavaScript 代码时效果很好,但现在当我在命令行中运行它时,我得到“未定义: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。 我确实收到控制台日志消息“现在该解析文件了。”,但随后收到消息“未定义:1”并且没有项目进入我的 DynamoDB 表。

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

parsedData.forEach(function(job) {

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

【问题讨论】:

  • readFileSync 的第二个参数是一个对象,所以它应该是 {encoding: "utf8"} nodejs.org/api/fs.html#fs_fs_readfilesync_path_options 您也可以尝试将其与 JSON.parse 分开,以确保这是导致问题的部分。跨度>
  • @JarredOlson - 删除了 fs,因为它似乎不适用于远程文件。我也确实将两个读取分开以隔离问题,但我仍然得到相同的结果。

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


【解决方案1】:

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

  1. 捆绑一个处理 http 请求的模块(例如请求模块),然后您可以使用它与远程文件进行交互,当它在 Lambda 上时,基本上它会像这样:
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 也存在类似的 Gem,它可以根据传入的 uri 做类似的事情。 这会是这样的:
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);
});

【讨论】:

  • 我无法让 fs 工作,所以我尝试了 http 模块,但我收到了“Undefined:1”消息。
  • 我认为您可能错误地使用了 http/fs 模块,更新了答案以包含使用 http[s] 模块的正确方法。此外,我建议您检查您提取的数据是否正确。
  • 此外,我建议您创建Update 小节,因为这有助于获得更多关于您所问的内容和您所拥有的内容,而不是用更新的方法完全改变问题完成和需要做什么