Использование Tidyverse для чтения данных из корзины S3 - PullRequest
1 голос
/ 08 апреля 2020

Я пытаюсь прочитать файл .csv, хранящийся в корзине s3, и получаю ошибки. Я следую инструкциям здесь , но либо это не работает, либо я делаю ошибку, и я не понимаю, что я делаю неправильно.

Вот что я пытаюсь сделать:

# I'm working on a SageMaker notebook instance
library(reticulate)
library(tidyverse)

sagemaker <- import('sagemaker')
sagemaker.session <- sagemaker$Session()

region <- sagemaker.session$boto_region_name
bucket <- "my-bucket"
prefix <- "data/staging"
bucket.path <- sprintf("https://s3-%s.amazonaws.com/%s", region, bucket)
role <- sagemaker$get_execution_role()

client <- sagemaker.session$boto_session$client('s3')
key <- sprintf("%s/%s", prefix, 'my_file.csv')

my.obj <- client$get_object(Bucket=bucket, Key=key)

my.df <- read_csv(my.obj$Body) # This is where it all breaks down:
## 
## Error: `file` must be a string, raw vector or a connection.
## Traceback:
## 
## 1. read_csv(my.obj$Body)
## 2. read_delimited(file, tokenizer, col_names = col_names, col_types = col_types, 
##  .     locale = locale, skip = skip, skip_empty_rows = skip_empty_rows, 
##  .     comment = comment, n_max = n_max, guess_max = guess_max, 
##  .     progress = progress)
## 3. col_spec_standardise(data, skip = skip, skip_empty_rows = skip_empty_rows, 
##  .     comment = comment, guess_max = guess_max, col_names = col_names, 
##  .     col_types = col_types, tokenizer = tokenizer, locale = locale)
## 4. datasource(file, skip = skip, skip_empty_rows = skip_empty_rows, 
##  .     comment = comment)
## 5. stop("`file` must be a string, raw vector or a connection.", 
##  .     call. = FALSE)

При работе с Python я могу прочитать файл CSV, используя что-то вроде этого:

import pandas as pd
# ... Lots of boilerplate code
my_data = pd.read_csv(client.get_object(Bucket=bucket, Key=key)['Body'])

Это очень похоже на то, что я пытаюсь делать в R, и он работает с Python ... так почему он не работает на R?

Можете ли вы указать мне правильный путь?

Примечание: Хотя я мог бы использовать для этого ядро ​​Python, я бы хотел придерживаться R, потому что я более свободно с ним справляюсь, чем с Python, по крайней мере, когда дело доходит до перехвата данных.

1 Ответ

1 голос
/ 11 апреля 2020

Я бы рекомендовал попробовать пакет aws.s3 вместо:

https://github.com/cloudyr/aws.s3

Довольно просто - установите переменные env:

Sys.setenv("AWS_ACCESS_KEY_ID" = "mykey",
           "AWS_SECRET_ACCESS_KEY" = "mysecretkey",
           "AWS_DEFAULT_REGION" = "us-east-1",
           "AWS_SESSION_TOKEN" = "mytoken")

и затем, когда это не так:

aws.s3::s3read_using(read.csv, object = "s3://bucket/folder/data.csv")

Обновление: я вижу, что вы также уже знакомы с boto и пытаетесь использовать сетку, поэтому оставляя эту простую обертку для этого здесь: https://github.com/cloudyr/roto.s3

Похоже, у него отличный API, например, переменная схема, которую вы намереваетесь использовать:

download_file(
  bucket = "is.rud.test", 
  key = "mtcars.csv", 
  filename = "/tmp/mtcars-again.csv", 
  profile_name = "personal"
)

read_csv("/tmp/mtcars-again.csv")
...