【问题标题】:Download AWS DynamoDB data to Excel with CSV format使用 CSV 格式将 AWS DynamoDB 数据下载到 Excel
【发布时间】:2022-11-23 23:42:01
【问题描述】:

我想将 AWS DynamoDB 数据下载到 Excel 以允许我在本地处理数据。但是,我还没有得到完美的 CSV 格式的数据。

我做了什么:我使用一个 Node.js 应用程序,它在 AWS Lambda 服务中运行以连接到 DynamoDB 数据库。此外,我可以从DynamoDB查询数据,然后将其转换为CSV格式,具体如下:

const AWS = require("aws-sdk");

AWS.config.update({ region: "us-east-1"})
const dynamo = new AWS.DynamoDB.DocumentClient({apiversion: "2012-08-10"});


exports.handler = async (event, context) => {
    
  let body;
  const headers = {
      "Content-Type": "text/csv",
      'Content-disposition': 'attachment; filename=testing.csv'
  };
  
 var params = {
     KeyConditionExpression: 'dataId = :id',
     ExpressionAttributeValues: {
         ':id': event.pathParameters.id,
     },
     TableName: "Table1",
 };
 body = await dynamo.query(params).promise();
        
 //-----------------------------------
 // convert json to csv
 const items = body.Items
 const replacer = (key, value) => value === null ? '' : value
 const header = Object.keys(items[0])
 let csv = [header.join(','), 
            ...items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
            ].join('\r\n')

body = JSON.stringify(csv);
  return {
     body,
     headers,
  };
};

上述解决方案有效,但输出并不完美;下面显示了一个示例(请注意,有三列:relativeHumidity、waterTemperature 和 airTemperature):

"relativeHumidity,waterTemperature,airTemperature\r\n26.123206154221034,21.716873058693757,23.859491598934557\r\n26.966163183232673,18.09642888420125,21.47952617547989\r\n33.79030978475366,18.995791668472204,17.451627574004128\r\n40.6641803491319,19.89060168145951,17.61247262137161"

但是,我想要一个如下所示的输出:

相对湿度、水温、空气温度 26.123206154221034,21.716873058693757,23.859491598934557 26.966163183232673,18.09642888420125,21.47952617547989 33.79030978475366,18.995791668472204,17.451627574004128 40.6641803491319,19.89060168145951,17.61247262137161

我将不胜感激有关如何实现这一目标的任何指南。请注意,我已经尝试过this,但数据正在以 json 格式导出到 S3。

【问题讨论】:

  • \r\n 行结尾如何给您带来问题?
  • 只需根据 \n 拆分,它就会给你一个字符串数组。
  • @jarmod 我不希望\r\n 成为检索到的数据的一部分。相反,我希望将其替换为实际的新行。
  • 但是您的代码是通过 join('\r\n') 明确执行此操作的。如果您只喜欢\n,是什么阻止了您进行更改?
  • 您是否简单地尝试过 join('\n') 然后返回 { body: csv, headers }`(没有尝试对 CSV 内容进行 JSON 化)?

标签: node.js json csv aws-lambda amazon-dynamodb


【解决方案1】:
let inputString =  `"relativeHumidity,waterTemperature,airTemperature
26.123206154221034,21.716873058693757,23.859491598934557
26.966163183232673,18.09642888420125,21.47952617547989
33.79030978475366,18.995791668472204,17.451627574004128
40.6641803491319,19.89060168145951,17.61247262137161"`;
let result = inputString.split("
");
result.forEach( val => {
  console.log(val);
})

【讨论】:

  • 如果我只想打印结果,这会起作用。但是,我想将数据下载为 CSV 文件。
  • 将其写入文件,将文件的绝对文件路径发送到下载URL。
  • AWS Lambda 要求返回一个与JSON.stringify 兼容的对象。我在没有 lambda 的情况下继续前进。因此,我转而使用 Express、Node.js 和主体解析器,它们简化了问题的解决方案。
【解决方案2】:

由于AWS Lambda 需要返回一个与 JSON.stringify 兼容的对象,我正在切换到 Express、Node.js 和 body-parser,这简化了问题的解决方案。

const bodyParser = require("body-parser");
const AWS = require("aws-sdk");
AWS.config.update({ region: "us-east-1" });
const dynamo = new AWS.DynamoDB.DocumentClient({ apiversion: "2012-08-10" });

const app = express();
const port = 3000;
app.use(bodyParser.json());

app.get("/", async (req, res) => {
  let body;
  res.setHeader(
    "Content-disposition",
    "attachment; filename=shifts-report.csv"
  );
  res.set("Content-Type", "text/csv");

  let csv;
  var params = {
    KeyConditionExpression: "deviceNameDate = :dnd",
    ExpressionAttributeValues: {
      ":dnd": "Factory1/Section1/Container1/2022-11-16",
    },
    ProjectionExpression: "waterTemperature, airTemperature, relativeHumidity",
    TableName: "factory1-section1-container1",
  };
  body = await dynamo.query(params).promise();

  // convert json to csv
  const items = body.Items;
  const replacer = (key, value) => (value === null ? "" : value);
  const header = Object.keys(items[0]);
  csv = [
    header.join(","),
    ...items.map((row) =>
      header
        .map((fieldName) => JSON.stringify(row[fieldName], replacer))
        .join(",")
    ),
  ].join("
");

  res.send(csv);
});

app.listen(port, () => {
  console.log(`App started on port ${port}`);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多