直接从服务器将 csv 文件上传到 aws s3 存储桶

Posted

技术标签:

【中文标题】直接从服务器将 csv 文件上传到 aws s3 存储桶【英文标题】:Upload csv file to aws s3 bucket directly from a server 【发布时间】:2019-10-23 08:58:24 【问题描述】:

祝大家周末愉快

我正在处理一项从 API 获取数据然后将它们存储到 csv 文件然后从那里直接上传到 AWS S3 存储桶的任务。我已经尝试了几种方法,但我目前被困在最后一点。任何帮助将不胜感激

我下面的代码将展示大部分问题以及我迄今为止一直在尝试的内容。

首先,我将从 API 获取数据
async systems() 
        const endpoint = sampleEndPoints.SYSTEMS
        return this.aggregateEndpoint(endpoint)
    
其次,我将获取取回的数据并将它们作为缓冲区放入 csv 文件中。 (因为我稍后必须将它们存储在fs.createReadStream
// generate JSON to Buffer
    async generateCsvToBuffer(json)
            const aws = this.config
            var ws = xlsx.utils.json_to_sheet(json)

            var wb = xlsx.utils.book_new();

          await xlsx.utils.book_append_sheet(wb, ws, 'Systems')

            const csvParsed = xlsx.write(wb,  type: 'buffer')


            return csvParsed;
    
第三,我从csvParsed 获得buffer data,以便将upload 发送到亚马逊AWS S3。问题就在这里,Body: fileStream.path 应该显示文件的 content 但不幸的是,它像这样从fs.createReadStream 注销

'"type":"Buffer","data":[80,75,3,4,10,0,0,0,0,0,249,117,199,78,214,146,124

 async uploadSample(file)
        const aws = this.config

        AWS.config.update(
          secretAccessKey: aws.secretAccessKey,
          accessKeyId: aws.accessKeyId,
          region: 'us-east-2'
        )


        const bufferObject = new Buffer.from(JSON.stringify(file))


     /*** WE NEED THE FILE SYSTEM IN ORDER TO STORE  */
        const fileStream = fs.createReadStream(bufferObject)


        const uploadParams = Bucket: aws.bucket, Key: aws.key, Body: fileStream.path


        const s3 = new AWS.S3()
       await s3.upload(uploadParams,null,function(error, file)
          if(error)
            console.log(error)
           else 
            console.log('Successfully uploaded')
          
        )
    
我的所有函数都将在server.js 中执行。因此,如果您查看此内容,您实际上可以了解问题的全貌
app.get('/systems/parsed', async(req, res) => 
    const Sample = await Sample()

//Fetch the data from an API 
    const systems = await Cache.remember('systems', async() => 
        return Sample.systems()
    )
    const integration = await IntegrationInstance()

/** GET THE RESPONSE DATA AND PUT THEM IN A CSV FILE*/
    const result = await integration.generateCsvToBuffer(systems)

    const aws = await AwsInstance()

/*** GET THE SYSTEMS FILE (CSV FILE) THEN UPLOAD THEM INTO THE AWS S3 BUCKET*/

    const awsUpload = await aws.uploadWorkedWithBuffer(result)


    return res.send(awsUpload);
)

我唯一关心的是,文件已成功上传到 Amazon AWS S3,但文件内容仍在 Buffer 中。对现有功能的任何帮助/任何更短的方法将不胜感激。

这是我的总结:从服务器获取数据 -> 将 Csv 文件作为缓冲区但从 Web 浏览器放入 -> 并从那里将其上传到 Amazon AWS S3 存储桶 -> 问题是文件已上传但文件的内容还在缓冲区中。

【问题讨论】:

【参考方案1】:

我真的解决了。

首先,每当您创建函数generateCsvToBuffer 时,请记住在您的wb(工作簿)上有一个bookType,以便s3 识别它。函数应该是这样的
    async generateCsvToBuffer(json)
            const aws = this.config
            var ws = xlsx.utils.json_to_sheet(json)

            var wb = xlsx.utils.book_new();

          await xlsx.utils.book_append_sheet(wb, ws, 'Systems')

            const csvParsed = xlsx.write(wb,  type: 'buffer', bookType: 'csv')

            return csvParsed;
    
其次,您必须将 Content-Disposition: attachment 导入到 uploadParams 中以进行 Aws 配置
 async uploadSample(file)
        const aws = this.config

        AWS.config.update(
          secretAccessKey: aws.secretAccessKey,
          accessKeyId: aws.accessKeyId,
          region: 'us-east-2'
        )


        const bufferObject = new Buffer.from(JSON.stringify(file))


     /*** WE NEED THE FILE SYSTEM IN ORDER TO STORE  */
        const fileStream = fs.createReadStream(bufferObject)


        const uploadParams = Bucket: aws.bucket, Key: aws.key, Body: fileStream.path


        const s3 = new AWS.S3()
       await s3.upload(uploadParams,null,function(error, file)
          if(error)
            console.log(error)
           else 
            console.log('Successfully uploaded')
          
        )
    

【讨论】:

【参考方案2】:

看起来你在这里让事情变得比必要的复杂。根据文档.upload,您可以直接将缓冲区传递给上传,而不是从缓冲区创建流。我怀疑您的根本问题是从流而不是流本身传递路径。

【讨论】:

感谢 Deadron 的建议,但我实际上尝试添加文件流本身但没有成功:( 只传入缓冲区而不尝试创建流。 我试了一下,结果还是一样,文件内容还是'"type":"Buffer","data":[80,75,3,4,10,0,0,0,0,0,249,117,199,78,214,146,124 我怀疑这是因为您的文件参数可能已经是一个 Buffer 并且您在其上调用 JSON.stringify 会导致它成为您看到的字符串。

以上是关于直接从服务器将 csv 文件上传到 aws s3 存储桶的主要内容,如果未能解决你的问题,请参考以下文章

将 CSV 文件从 JSON 数据上传到 S3 存储桶

将 CSV 流从 Ruby 上传到 S3

将 Dataframe 保存到 csv 直接保存到 s3 Python

如何使用 Python 在 myBucket 中上传 CSV 文件并在 S3 AWS 中读取文件

从静态网页上传 csv 文件到 S3 存储桶

使用 python 从 AWS S3 到 PostgreSQL Amazon RDS 的 CSV 文件