【问题标题】:Keep alive function for PostgreSQL connection in Shiny app?Shiny 应用程序中 PostgreSQL 连接的保持活动功能?
【发布时间】:2016-03-15 01:40:41
【问题描述】:

我有一个 shiny 应用程序,它利用 RPostgreSQL 连接到数据库并临时查询数据。

# Initialize environment to hold SQL parameters:
library(RPostgreSQL)
if (!exists('.sql')) .sql <- new.env()
.sql$cxn <- dbConnect(PostgreSQL(), host = "localhost", dbname = "testdb", user = "myuser", password = "Passw0rd!", port = 5432)

此代码在应用初始化时运行,但一段时间后,连接被服务器终止:

> dbGetQuery(.sql$cxn, "SELECT 1")
Error in postgresqlExecStatement(conn, statement, ...) : 
  RS-DBI driver: (could not run statement: no connection to the server
)

如果我只是打电话:

.sql$cxn <- dbConnect(PostgreSQL(), host = "localhost", dbname = "testdb", user = "myuser", password = "Passw0rd!", port = 5432)

再次,它创建了第二个连接:(我想要那个)

> dbListConnections(PostgreSQL())
[[1]]
<PostgreSQLConnection:(10601,4)> 

[[2]]
<PostgreSQLConnection:(10601,5)> 

(最终,已达到最大连接数,您无法创建另一个:https://groups.google.com/forum/#!topic/shiny-discuss/0VjQc2a6z3M

我想创建一个连接到我的 PostgreSQL 数据库的函数(如果它还没有),并保持连接打开(通过 SELECT'ing 1)如果它有:

getConnection <- function(.host, .user, .pw) {
  tryCatch({
    if (!exists('cxn', where = .sql)) {
      .sql$cxn <- dbConnect(PostgreSQL(), host = .host, dbname = "testdb", user = .user, password = .pw, port = 5432)
    } else {
      dbGetQuery(.sql$cxn, "SELECT 1")
    }
  }, warning = function(w) {
    NULL  # placeholder for warnings
  }, error = function(e) {
    print(e)
    cat("Looks like PostgreSQL connection died. Let's try to reconnect...\n")
    invisible(lapply(dbListConnections(PostgreSQL()), dbDisconnect))  # Close all db connections
.sql$cxn <<- dbConnect(PostgreSQL(), host = .host, dbname = "testdb", user = .user, password = .pw, port = 5432)
  }, finally = {
    return(.sql$cxn)
  })
}

getConnection(.host = "localhost", .user = "myuser", .pw = "Passw0rd!")

EDIT 2016/03/12:不知道为什么,但我上面写的函数似乎不能正常工作......

当我调用它时,我得到:

> getConnection(.host = awsrds$host, .user = awsrds$username, .pw = awsrds$password)
Error in postgresqlExecStatement(conn, statement, ...) : 
  RS-DBI driver: (could not run statement: no connection to the server
)
<PostgreSQLConnection:(12495,0)> 

特别是dbGetQuery(.sql$cxn, "SELECT 1")这部分返回:

Error in postgresqlExecStatement(conn, statement, ...) : 
  RS-DBI driver: (could not run statement: no connection to the server
)
NULL
Warning message:
In postgresqlQuickSQL(conn, statement, ...) :
  Could not create executeSELECT 1

这个输出的classNULL(而不是错误?)。

任何想法我做错了什么?谢谢!

【问题讨论】:

  • 能不能每次用完就关闭连接?出于性能原因,保持连接是必要的吗?
  • @warmoverflow 不幸的是,连接必须保持打开状态。任意数量的用户在任何给定时刻都在访问应用程序并可能查询数据库。
  • 我的理解(可能是错误的)是每个用户都运行自己的 Shiny 会话,因此每个用户都将连接/断开数据库而不影响其他用户,只要您的代码组织正确(参见shiny.rstudio.com/articles/scoping.html)

标签: r shiny shinydashboard rpostgresql


【解决方案1】:

我相信您可以通过在您的连接功能中添加检查来解决该错误。这就是我为 mysql 所做的......我相信在你的情况下应该工作相同。关键是检查SELECT 1 == 'try-error'

connectionFunction <- function() {
  if (!exists("connectionName", where = .GlobalEnv)) {
      connectionName <<- dbConnect(MySQL(), default.file = mysqlconf, dbname = "dbName")
  } else if (class(try(dbGetQuery(connectionName, "SELECT 1"))) == "try-error") {
      dbDisconnect(connectionName)
      connectionName <<- dbConnect(MySQL(), default.file = mysqlconf, dbName = "dbName")
  }
  return(connectionName)

}

【讨论】:

    猜你喜欢
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 2016-10-09
    相关资源
    最近更新 更多