Бих искал да използвам синтаксис 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.