【问题标题】:s3.save a json file to aws s3s3.将 json 文件保存到 aws s3
【发布时间】:2020-03-07 00:15:49
【问题描述】:

我正在尝试将格式正确的 json 文件保存到 aws s3。

我可以使用例如将常规数据框保存到 s3

library(tidyverse)
library(aws.s3)
s3save(mtcars, bucket = "s3://ourco-emr/", object = "tables/adhoc.db/mtcars/mtcars")

但我需要将 mtcars 转换为 json 格式。特别是ndjson。

我可以创建一个格式正确的 json 文件,例如:

predictions_file <- file("mtcars.json")
jsonlite::stream_out(mtcars), predictions_file)

这会将一个名为 mtcars.json 的文件保存到我的目录中。

但是,使用 aws.s3 函数 s3save(),我需要发送内存中的对象,而不是文件。

试过了:

predictions_file <- file("mtcars.json")
s3write_using(mtcars, 
              FUN = jsonlite::stream_out,
              con = predictions_file,
              "s3://ourco-emr/", 
              object = "tables/adhoc.db/mtcars/mtcars")

给予:

if (verbose) message("opening ", is(con), " output connection.") 中的错误: 论点不能解释为合乎逻辑的

我尝试了相同的代码块,但省略了 con=predictions_file 的行,刚刚给出:

参数 con 必须是一个连接。

如果函数 jsonlite::stream_out() 创建了一个格式正确的 json 文件,那么我该如何将该文件写入 s3?

编辑: 所需的 json 输出如下所示:

{"mpg":21,"cyl":6,"disp":160,"hp":110,"drat":3,"wt":2,"qsec":16,"vs":0,"am":1,"gear":4,"carb":4,"year":"2020","month":"03","day":"05"}
{"mpg":21,"cyl":6,"disp":160,"hp":110,"drat":3,"wt":2,"qsec":17,"vs":0,"am":1,"gear":4,"carb":4,"year":"2020","month":"03","day":"05"}
{"mpg":22,"cyl":4,"disp":108,"hp":93,"drat":35,"wt":2,"qsec":18,"vs":1,"am":1,"gear":4,"carb":1,"year":"2020","month":"03","day":"05"}
{"mpg":21,"cyl":6,"disp":258,"hp":110,"drat":8,"wt":3,"qsec":19,"vs":1,"am":0,"gear":3,"carb":1,"year":"2020","month":"03","day":"05"}
{"mpg":18,"cyl":8,"disp":360,"hp":175,"drat":3,"wt":3,"qsec":17,"vs":0,"am":0,"gear":3,"carb":2,"year":"2020","month":"03","day":"05"}

尝试使用 readchar 时:

mtcars_string <- readChar("mtcars.json", 1e6)
s3save(mtcars_string, bucket = "s3://ourco-emr/", object = "tables/adhoc.db/mtcars/2020/03/06/mtcars")

如果我随后下载并打开生成的 json 文件,它看起来像这样:

5244 5833 0a58 0a00 0000 0300 0306 0000
0305 0000 0000 0555 5446 2d38 0000 0402
0000 0001 0004 0009 0000 000d 6d74 6361
7273 5f73 7472 696e 6700 0000 1000 0000
0100 0400 0900 0012 347b 226d 7067 223a
3231 2c22 6379 6c22 3a36 2c22 6469 7370

所以看起来 tsb 已发送到 aws s3 而不是 json

【问题讨论】:

  • 你不能只是my_string &lt;- readChar("myfile.json", 1e6)和s3save(my_string)吗?
  • 这似乎允许我保存,但格式丢失了。感觉已经很近了。将添加对 json 应如何显示的编辑
  • 也许你可以使用jsonlite::write_json?
  • @DiceboyT write_json 不会在 nbjson 中正确格式化,这是我最初尝试的。
  • my_raw &lt;- readBin("myjson.json", "raw", 1e6) 和 s3write_using(my_raw, writeBin) 怎么样?那应该是磁盘和 s3 之间的逐字节复制。

标签: r amazon-web-services amazon-s3 jsonlite


【解决方案1】:

我遇到了同样的问题。我需要编写 JSON 行 (ndjson) 并将其上传到 S3,据我所知,只有 jsonlite-package 中的 stream_out() 会写入 JSON 行。

stream_out() 仅将连接对象作为目标,s3write_using(),但是,写入临时文件tmp 并将该文件的路径作为字符串传递给FUN。 stream_out() 然后抛出错误:

参数 con 必须是一个连接。

暂时的解决方法是修改 s3write_using() 以将连接传递给 FUN 而不是文件路径字符串。

  1. trace(s3write_using, edit=TRUE) - 打开编辑器

  2. 更改第 5 行:
    value &lt;- FUN(x, tmp, ...)

    致此:
    value &lt;- FUN(x, file(tmp), ...)

然后您可以使用stream_out() 上传数据:

s3write_using(x = data, 
              FUN = stream_out,
              bucket = 'mybucket',
              object = 'my/object.json',
              opts = list(acl = "private", multipart = FALSE, verbose = T, show_progress = T))

编辑会在整个会话期间保留,或者直到您执行 untrace(s3write_using)。

可能应该在他们的 cloudyr/aws.s3 GitHub 中提交请求,因为这是一个常见的用例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2018-06-08
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 2018-04-25
    相关资源
    最近更新 更多