>目标:将RJDBC与OpenCPU AJAX Post调用一起使用。
用例:我需要连接Apache凤凰数据库并获取一些数据。在这些数据上,我应该进行分析。所以要连接凤凰城,我使用的是 rjdbc(凤凰城不支持任何其他连接选项)。
环境 : public.opencpu.org
这是我正在尝试的:
.html
<textarea>
library(RJDBC)
.. do some data fetching and then r statistics
</textarea>
<br />
<button id="submitbutton" >Execute</button>
<br />
<br />
<div id="output">
</div>
JavaScript
<script type="text/javascript">
//When Document is Ready
$(function () {
var baseurl = "https://public.opencpu.org";
//because identity is in base
ocpu.seturl(baseurl+"/ocpu/library/base/R");
//actual handler
$("#submitbutton").on("click", function(){
//arguments
var mysnippet = new ocpu.Snippet($("#input").val());
//perform the request
var req = ocpu.call("identity", {
"x" : mysnippet
}, function(session){
session.getStdout(function(outtxt){
$("#output-txt").text(outtxt);
});
});
//if R returns an error, alert the error message
req.fail(function(){
alert("Server error: " + req.responseText);
$("#output").hide();
});
req.always(function(){
$("button").removeAttr("disabled");
});
});
});
</script>
场景
当我单击执行按钮时,从文本区域获取用户输入的值(此处库(RJDBC)和一些数据库操作)并发送ajax帖子并回复以下错误
谷歌浏览器控制台日志:
POST https://public.opencpu.org/ocpu/library/base/R/identity 400 (Bad Request)
OpenCPU error HTTP 400
package 'rJava' could not be loaded
希望这能更清晰。
需要确认rJava是否适用于OpenCPU,如果有的话,是否有任何可能的解决方法来解决这个问题?
我的解决方案的核心如下所示。 该代码取自具有一些日志记录的 R6 类。 为了记录正在发生的事情,我保留了private$log
命令,但如果运行此代码的版本,则需要将其省略。 同样,那里有对函数的调用,你真的不需要完成工作,我将主机信息打包在一个列表中,而不是为密码等传递单个变量。 简而言之,我在这里提供的代码不是最低限度可复制的。
但是,我在此要点中提供的代码应该在某种程度上是可复制的(一旦您提供了数据库连接,classPath
和driverClass
)。 该要点已被大约 0 清理,因此其中有大量代码严格来说对于完成工作是多余的。这些代码都不漂亮、优雅等——一般来说,我为此感到羞耻,但本着分享的精神,我还是把它放了出来。
解释性代码段:
jvmNode <- makeCluster(1, methods=FALSE, port = sample(11000:11999,1), rscript_args="--vanilla")
connected <- isTRUE(try(clusterEvalQ(jvmNode, 2)==2, silent=TRUE))
private$log$finest("forkable node started")
clusterEvalQ(jvmNode,{library(DBI);library(rJava);library(RJDBC)})
clusterEvalQ(jvmNode, systemRAMFree <- function() {
#in GB, platform dependent
as.numeric(system('FREE_KB=$(($(echo `sed -n '2p;3p;4p' < /proc/meminfo | sed "s/ \+/ /g" | cut -d' ' -f 2 ` | sed "s/ /+/g")));echo $FREE_KB', intern=TRUE))/1024/1024
})
clusterEvalQ(jvmNode, options(java.parameters = paste0("-Xmx",systemRAMFree(),"g")))
hostInformation <- private$hostInformation
classPath <- "~/redshift/redshiftJDBC41.jar"
driverClass <- private$driverClass
java.parameters <- getOption("java.parameters")
toExportList <- list(statement,driverClass, classPath, hostInformation, java.parameters)
names(toExportList) <- c("statement","driverClass","classPath", "hostInformation", "java.parameters")
toExport <- as.environment(toExportList)
clusterExport(jvmNode, ls(toExport), envir=toExport)
clusterEvalQ(jvmNode, options(java.parameters = java.parameters))
clusterEvalQ(jvmNode, rJava::.jinit())
private$log$finest("JVM Started")
clusterEvalQ(jvmNode, drv <- RJDBC::JDBC(driverClass, classPath))
private$log$finest("Driver obtained")
clusterEvalQ(jvmNode, conn <- dbConnect(drv,
url = hostInformation$host,
user = hostInformation$user,
password = hostInformation$password))
private$log$debug(logPrefix("query:", statement))
result <- try(clusterEvalQ(jvmNode, dbGetQuery(conn, statement))[[1]])
clusterEvalQ(jvmNode, dbDisconnect(conn))
stopCluster(jvmNode)