【问题标题】:AWS S3 - Retreive multiple files and merge them afterAWS S3 - 检索多个文件并在之后合并它们
【发布时间】:2021-12-29 17:02:09
【问题描述】:

我正在尝试从 AWS S3 存储桶中提取多个文件,并愿意在之后合并所有文件的响应。

例如,我有以下文件:

my-bucket/mainfile1.json.gz
my-bucket/mainfile2.json.gz
my-bucket/mainfile3.json.gz

目前我正在访问这样的单个文件:

const unzipFromS3 = (key, bucket) => {
  
  return new Promise(async (resolve, reject) => {

    AWS.config.loadFromPath(process.env["PWD"]+'/private/awss3/s3_config.json'); 
    var s3 = new AWS.S3();

    let options = {
      'Bucket': "my-bucket",
      'Key':    "mainfile1.json.gz",
    };

    s3.getObject(options, function(err, res) {
      if(err) return reject(err);
      
      resolve(zlib.unzipSync(res.Body).toString());
    });
  });
};

unzipFromS3().then(function(result){

  console.dir(result);
});

现在这非常适合单个文件,但是如果我想合并来自 3 个单独文件的数据,如何使用多个文件来实现呢?

【问题讨论】:

  • 是什么阻止您多次执行此操作,然后在全部完成后,连接或以其他方式合并生成的 gz 文件?
  • 我无法在具有多个键的 aws 文档中找到任何内容
  • 没有SDK函数可以在同一个调用中获取多个对象。您只需进行多次下载,每个对象一个。当all complete 时,继续进行合并。
  • @jarmod 我真的不擅长 javascript,你能用 Promise.all 功能发布答案吗?

标签: javascript node.js amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

这是一个关于如何从 S3 读取 gzip 压缩的 JSON 文件,解压缩它们,然后合并生成的 JavaScript 对象,最后 gzip 并将合并的结果写回 S3 的初步想法。

const aws = require('aws-sdk');
const zlib = require('zlib');
const s3 = new aws.S3();

const BUCKET = 'mybucket';
const PREFIX = '';
const FILES = ['test1.json.gz', 'test2.json.gz', 'test3.json.gz'];

(async () => {
  const promises = [];

  try {
    for (let ii = 0; ii < FILES.length; ii++) {
      const params = {
        Bucket: BUCKET,
        Key: `${PREFIX}${FILES[ii]}`,
      };
      console.log('Get:', params.Key, 'from:', params.Bucket);
      promises.push(s3.getObject(params).promise());
    }

    const results = await Promise.all(promises);
    const buffers = results.map(result => result.Body);
    const content = buffers.map(buffer => JSON.parse(zlib.unzipSync(buffer).toString()));
    console.log('Read OK', JSON.stringify(content));

    const merged = Object.assign({}, ...content);
    console.log('Merged content', JSON.stringify(merged));

    const params = {
      Bucket: BUCKET,
      Key: `${PREFIX}result/test.json.gz`,
      Body: zlib.gzipSync(JSON.stringify(merged), 'utf8'),
    };

    console.log('Put:', params.Key, 'to:', params.Bucket);
    const rc = await s3.putObject(params).promise()
  } catch (err) {
    console.log(err, err.stack);
    throw err;
  }
})();

【讨论】:

  • 如果找不到文件,它会在这一行崩溃: const results = await Promise.all(promises);
  • 是的,您需要添加 error handling 以防 Promise 被拒绝。
  • 您能否编辑您的答案并放置该错误处理程序。那太好了
  • 代码实际上已经有一个异常处理程序。它使用堆栈跟踪打印异常,然后重新抛出异常。您可以更改此处理程序以执行您需要的任何自定义错误处理。
  • 其实我不希望它崩溃,我在数组中有文件,所以如果某个文件不存在我想跳过它,在当前情况下它会破坏脚本
猜你喜欢
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多