почему future :: future () не работает с dbAppendTable в блестящем? - PullRequest
1 голос
/ 26 октября 2019

вы можете использовать future () для его побочных эффектов, например, для записи файла:

library(promises)
library(future)
plan(multiprocess)
future({write.csv(mtcars,"mtcars.csv")})

, но вы не можете с помощью вызова базы данных:

library(RSQLite)
library(promises)
library(future)
plan(multiprocess)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
future({
dbCreateTable(con, "iris", iris)
})
dbReadTable(con, "iris") # gives error

(таблица не создается независимо от того, ведется ли запись постоянно или в памяти.)

Ответы [ 2 ]

2 голосов
/ 26 октября 2019

Пакет DBI и все его реализации (например, RSQLite) используют неэкспортируемые объекты (в основном указатели памяти), см .:

https://cran.r-project.org/web/packages/future/vignettes/future-4-non-exportable-objects.html

Вы можете увидеть сообщение об ошибке при настройке futures, например:

options(future.globals.onReference = "error")
# ... your code goes here

# Error in FALSE : 
# Detected a non-exportable reference (‘externalptr’) in one of the globals (‘con’ of class ‘SQLiteConnection’) used in the future expression
# Timing stopped at: 0.028 0 0.028
0 голосов
/ 26 октября 2019

Я могу ошибаться, но я подозреваю, что два con не совпадают, поэтому я предполагаю, что будущее похоже на Бангкок в похмелье: То, что происходит внутри будущего, остается внутри будущего . Ваш con, так сказать, оценивается по значению (не по ссылке), поэтому таблица не записывается в оригинал con. Рассмотрим следующий код:

library(future)
x <- 4
a <- future({
    x <- x + 1 # I am not seen outside
})
x # is still 4 and has not changed
#> [1] 4
value(a) # is 5
#> [1] 5

Однако, если вы используете substitute = FALSE в своем future, x также будет 5, и я буду рад узнать, почему :-)

...