【问题标题】:Node.js Cloud Function - Stream CSV data directly to Google Cloud Storage fileNode.js Cloud Function - 将 CSV 数据直接流式传输到 Google Cloud Storage 文件
【发布时间】:2020-01-15 12:47:09
【问题描述】:

我有一个脚本,它可以调用 RESTful API 并以块的形式从报告中检索 CSV 数据。我能够在控制台中连接、解析和显示这些数据。我还可以将此 CSV 数据写入本地文件并存储。

我想弄清楚的是如何在将这些数据上传到 GCS 之前跳过创建文件来存储这些数据,而是直接将其传输到 Google Cloud Storage 以另存为文件。由于我正在尝试使其成为无服务器云功能,因此我尝试将其直接从内存流式传输到 Google Cloud Storage 文件中。

我在 google 上找到了这个 'Streaming Transfers' 文档,但它只引用了使用“gsutil”执行此操作,我正在努力寻找有关如何使用 node.js 执行此操作的任何示例或文档。我还尝试在堆栈溢出时关注此answer,但它是从 2013 年开始的,这些方法似乎有点过时了。我的脚本也不是面向用户的,所以我不需要打任何路线。

我可以使用以下功能将本地文件直接上传到我的存储桶,因此身份验证不是问题。我只是不确定如何将内存中的 CSV blob 或对象转换为 GCS 中的文件。我找不到很多例子,所以不确定过去是否有其他人解决过这个问题。

const { Storage } = require('@google-cloud/storage');
const storage = new Storage({
  projectId,
  keyFilename
 });

function uploadCSVToGCS() {
   const localFilePath = './test.csv';
   const bucketName = "Test_Bucket";
   const bucket = storage.bucket(bucketName);

   bucket.upload(localFilePath);
};

我还发现了一个名为 'boto' 的 Google 引用的第 3 方插件,它似乎可以满足我的要求,但不幸的是,这是用于 python,而不是 node.js。

【问题讨论】:

    标签: node.js upload google-cloud-functions google-cloud-storage


    【解决方案1】:

    documentation 中说明了将对象数据流式传输到 Cloud Storage。您需要了解node streams 的工作原理,并使用createWriteStream。示例代码并不完全符合您的要求,但您将使用相同的模式:

    function sendUploadToGCS (req, res, next) {
      if (!req.file) {
        return next();
      }
    
      const gcsname = Date.now() + req.file.originalname;
      const file = bucket.file(gcsname);
    
      const stream = file.createWriteStream({
        metadata: {
          contentType: req.file.mimetype
        },
        resumable: false
      });
    
      stream.on('error', (err) => {
        req.file.cloudStorageError = err;
        next(err);
      });
    
      stream.on('finish', () => {
        req.file.cloudStorageObject = gcsname;
        file.makePublic().then(() => {
          req.file.cloudStoragePublicUrl = getPublicUrl(gcsname);
          next();
        });
      });
    
      stream.end(req.file.buffer);
    }
    

    【讨论】:

    • 这个例子不是仍然只是发送从表单提交的预先存在的文件吗?这个例子中的 req 里面有一个文件,对吧?我想我感到困惑的地方是我如何将从 API 调用返回的 csv 数据块提供给“createWriteStream”函数。在我的情况下,我是否只是将其设置为“req.file”常量?
    • 如果您的源有一个流,您应该能够将其通过管道传输到 Cloud Storage 的写入流中。您将需要弄清楚该源流是什么。我不认为有任何避免需要了解节点流是如何工作的,因为这是写入对象原始数据的工具。
    【解决方案2】:

    @doug-stevenson 感谢您将我推向正确的方向。我能够让它与以下代码一起工作:

    const { Storage } = require('@google-cloud/storage');
    const storage = new Storage();
    const bucketName = 'test_bucket';
    const blobName = 'test.csv';
    const bucket = storage.bucket(bucketName);
    const blob = bucket.file(blobName);
    const request = require('request');
    
    
    function pipeCSVToGCS(redirectUrl) {
          request.get(redirectUrl)
          .pipe(blob.createWriteStream({
              metadata: {
                  contentType: 'text/csv'
              }
          }))
        .on("error", (err) => {
            console.error(`error occurred`);
        })
        .on('finish', () => {
            console.info(`success`);
        });
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 2021-12-30
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-04-25
      • 1970-01-01
      相关资源
      最近更新 更多