Чтение данных непосредственно из двоичного большого объекта (BLOB) - PullRequest
3 голосов
/ 13 января 2020

Я пытаюсь создать базу данных SQLite для хранения (XLS) файлов для моего приложения Shiny. Идея состоит в том, что людям не нужно будет повторно загружать свой контент каждую сессию - он будет сохранен и ждет их. Я хочу хранить необработанные файлы - в настоящее время я использую только часть из них, но я подумал, что безопаснее хранить необработанные данные.

Я успешно создал Po C SQLite DB, которая хранит файлы XLSX в виде больших двоичных объектов, но я не могу использовать, например, readxl::read_excel() для чтения их в R напрямую из BLOB. Сейчас я сохраняю их во временном файле и затем читаю нормально (код ниже). Есть ли более эффективный способ сделать это? Могу ли я прочитать BLOB напрямую?

library(RSQLite)
library(readxl)

# open connection, create DB
con <- dbConnect(RSQLite::SQLite(), "file_db.sqlite")
dbExecute(con, "CREATE TABLE files (
                                    file_id INTEGER PRIMARY KEY AUTOINCREMENT,
                                    filename TEXT,
                                    file BLOB
                                    )"
)
#> [1] 0

# path to xlsx
xlsx_path <- readxl_example("datasets.xlsx")

# open connection in binary mode and read file
file = file(xlsx_path, "rb")
file_raw = readBin(file, what = "raw", n = 1e10)
close(file)

# preapare row of data to write in DB
row_to_db <- data.frame(
  filename = "datasets.xlsx",
  file = I(list(file_raw)),
  stringsAsFactors = FALSE
)

dbAppendTable(con, "files", row_to_db)
#> [1] 1

db_data <- 
  dbGetQuery(con, "SELECT * FROM files")

db_data
#>   file_id      filename           file
#> 1       1 datasets.xlsx blob[54.45 kB]

# workaround:
# save temp file
temp_file_path = tempfile(# determine file format
                          fileext = ifelse(identical(db_data$ALS_file[[1]][1:4],
                                                      as.raw(c(0x50, 0x4b, 0x03, 0x04))),
                                            ".xlsx",
                                            ".xls"))
temp_file = file(temp_file_path, open = "wb")
writeBin(db_data$file[[1]], con = temp_file)
close(temp_file)

read_xlsx(path = temp_file_path)
#> # A tibble: 150 x 5
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>           <dbl>       <dbl>        <dbl>       <dbl> <chr>  
#>  1          5.1         3.5          1.4         0.2 setosa 
#>  2          4.9         3            1.4         0.2 setosa 
#>  3          4.7         3.2          1.3         0.2 setosa 
#>  4          4.6         3.1          1.5         0.2 setosa 
#>  5          5           3.6          1.4         0.2 setosa 
#>  6          5.4         3.9          1.7         0.4 setosa 
#>  7          4.6         3.4          1.4         0.3 setosa 
#>  8          5           3.4          1.5         0.2 setosa 
#>  9          4.4         2.9          1.4         0.2 setosa 
#> 10          4.9         3.1          1.5         0.1 setosa 
#> # ... with 140 more rows

dbDisconnect(con)

Создано в 2020-01-13 пакетом представлением (v0.3.0)

Информация о сеансе

devtools::session_info()
#> - Session info ---------------------------------------------------------------
#>  setting  value                       
#>  version  R version 3.6.1 (2019-07-05)
#>  os       Windows 10 x64              
#>  system   x86_64, mingw32             
#>  ui       RTerm                       
#>  language (EN)                        
#>  collate  Polish_Poland.1250          
#>  ctype    Polish_Poland.1250          
#>  tz       Europe/Warsaw               
#>  date     2020-01-13                  
#> 
#> - Packages -------------------------------------------------------------------
#>  package     * version date       lib source        
#>  assertthat    0.2.1   2019-03-21 [1] CRAN (R 3.6.1)
#>  backports     1.1.5   2019-10-02 [1] CRAN (R 3.6.1)
#>  bit           1.1-14  2018-05-29 [1] CRAN (R 3.6.0)
#>  bit64         0.9-7   2017-05-08 [1] CRAN (R 3.6.0)
#>  blob          1.2.0   2019-07-09 [1] CRAN (R 3.6.2)
#>  callr         3.3.2   2019-09-22 [1] CRAN (R 3.6.1)
#>  cellranger    1.1.0   2016-07-27 [1] CRAN (R 3.6.1)
#>  cli           1.1.0   2019-03-19 [1] CRAN (R 3.6.1)
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.6.1)
#>  DBI           1.1.0   2019-12-15 [1] CRAN (R 3.6.2)
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 3.6.1)
#>  devtools      2.2.1   2019-09-24 [1] CRAN (R 3.6.1)
#>  digest        0.6.23  2019-11-23 [1] CRAN (R 3.6.1)
#>  ellipsis      0.3.0   2019-09-20 [1] CRAN (R 3.6.1)
#>  evaluate      0.14    2019-05-28 [1] CRAN (R 3.6.1)
#>  fansi         0.4.0   2018-10-05 [1] CRAN (R 3.6.1)
#>  fs            1.3.1   2019-05-06 [1] CRAN (R 3.6.1)
#>  glue          1.3.1   2019-03-12 [1] CRAN (R 3.6.1)
#>  highr         0.8     2019-03-20 [1] CRAN (R 3.6.1)
#>  htmltools     0.4.0   2019-10-04 [1] CRAN (R 3.6.1)
#>  knitr         1.26    2019-11-12 [1] CRAN (R 3.6.1)
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 3.6.1)
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.6.1)
#>  pillar        1.4.2   2019-06-29 [1] CRAN (R 3.6.1)
#>  pkgbuild      1.0.6   2019-10-09 [1] CRAN (R 3.6.1)
#>  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 3.6.1)
#>  pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.6.1)
#>  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.6.1)
#>  processx      3.4.1   2019-07-18 [1] CRAN (R 3.6.1)
#>  ps            1.3.0   2018-12-21 [1] CRAN (R 3.6.1)
#>  R6            2.4.1   2019-11-12 [1] CRAN (R 3.6.1)
#>  Rcpp          1.0.3   2019-11-08 [1] CRAN (R 3.6.1)
#>  readxl      * 1.3.1   2019-03-13 [1] CRAN (R 3.6.1)
#>  remotes       2.1.0   2019-06-24 [1] CRAN (R 3.6.1)
#>  rlang         0.4.2   2019-11-23 [1] CRAN (R 3.6.1)
#>  rmarkdown     1.18    2019-11-27 [1] CRAN (R 3.6.1)
#>  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.6.1)
#>  RSQLite     * 2.2.0   2020-01-07 [1] CRAN (R 3.6.1)
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.6.1)
#>  stringi       1.4.3   2019-03-12 [1] CRAN (R 3.6.0)
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 3.6.1)
#>  testthat      2.3.1   2019-12-01 [1] CRAN (R 3.6.1)
#>  tibble        2.1.3   2019-06-06 [1] CRAN (R 3.6.1)
#>  usethis       1.5.1   2019-07-04 [1] CRAN (R 3.6.1)
#>  utf8          1.1.4   2018-05-24 [1] CRAN (R 3.6.1)
#>  vctrs         0.2.0   2019-07-05 [1] CRAN (R 3.6.1)
#>  withr         2.1.2   2018-03-15 [1] CRAN (R 3.6.1)
#>  xfun          0.11    2019-11-12 [1] CRAN (R 3.6.1)
#>  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.6.0)
#>  zeallot       0.1.0   2018-01-28 [1] CRAN (R 3.6.1)
#> 
#> [1] C:/Users/sijkok/Documents/R/win-library/3.6
#> [2] C:/Program Files/R/R-3.6.1/library

...