/ / RODBC & foreach - r, foreach, паралелна обработка, rodbc

RODBC & foreach - r, foreach, паралелна обработка, rodbc

Бих искал да използвам синтаксис foreach за запитване на локално съхранена база данни.

Моят код изглежда така:

h <- odbcDriverConnect(connection)

cl<-makeCluster(no_cores)
registerDoParallel(cl)

foreach(i = 1:dim(Table)[1],
.combine = rbind,
.export = "h",
.packages = "RODBC")  %dopar%  {
cat(i,"n")
#h <- odbcDriverConnect(connection)
sqlQuery(query)
}

odbcCloseAll()
stopCluster(cl)

Когато използвам% do% вместо% dopar%, той работи правилно, но когато се опитвам да го направя паралелно получавам тази грешка

Грешка в {: task 1 failed - "първият аргумент не е отворен RODBC channel "В допълнение: Предупредително съобщение: В e $ fun (obj, заместител (ex), parent.frame (), e $ data): вече експортира променлива (и): h

Когато поставям h в цикъла foreach, той работи,но разбирам, че създавам връзка на всяка отделна стъпка и бих искал да избегна това. Има ли някакъв начин да експортирам тази връзка към foreach (по същия начин, по който се прави с други променливи)?

Отговори:

0 за отговор № 1

Не можете да експортирате връзки към базата данни вработници, защото те не могат да бъдат правилно сериализирани и десериализирани (тъй като съдържат неща като гнездови връзки) .Вместо това трябва да ги създадете на работниците, но за ефективност, трябва да ги създадете веднъж и след това да ги използвате многократно от вашите кръгове ,

Тъй като използвате doParallel, можете да инициализирате работниците с clusterEvalQ:

clusterEvalQ(cl, {
library(RODBC)
connection <- "???"  # how are you setting this?
h <- odbcDriverConnect(connection)
})

След това можете да го използвате h от цикъла на foreach, стига да предотвратите foreach от автоматично експортиране h на работниците:

foreach(i = 1:dim(Table)[1],
.combine = rbind,
.noexport = "h",  # make sure h is *not* exported!
.packages = "RODBC")  %dopar%  {
cat(i, "n")
sqlQuery(h, query)
}

Важно е да се използва .noexport="h"иначе доброто h ще бъде маскиран и ще получите грешка от RODBC.