关闭R Shiny App时与PostgreSQL断开连接

时间:2015-07-02 18:25:23

标签: r shiny rpostgresql

这个问题与this question类似,但提供的答案对我的例子来说还不够。

我正在创建一个连接到数据库的Shiny App。用户可以提供一些输入,并运行一些“预制”查询。现在,我想确保在退出应用程序时关闭与数据库的连接。我可以使用一个按钮和stopApp功能,但这假设用户会很好并且总是点击所述按钮。用户有时可能会关闭窗口而不打开数据库连接,因此我想找到一种在用户关闭应用程序窗口时显式关闭连接的方法。

我想一个解决方案是实例化一个新连接,并在每个查询结束时关闭,但这似乎效率低下。

这是一些用于演示此问题的工作代码。如果我从Rstudio运行此应用程序然后关闭窗口,我仍然按照dbListConnections(PostgreSQL())建立连接。将dbDisconnect(con)附加到文件末尾无济于事。

library(shiny)
library(RPostgreSQL)

server <- shinyServer(function(input, output){
  # Read in the dataset
  connectDB <- eventReactive(input$connectDB, {

    if(input$drv != "postgresql"){
      stop("Only 'postgresql' implemented currently")
    }else{
      drv <- dbDriver("PostgreSQL")
      port = 5432
    }

    con <- dbConnect(drv, user = input$user, password = input$passwd, 
                     port = port, host = input$server, dbname=input$db_name)
    con
  })

  output$test <- renderText({
    con <- connectDB()
    "connection success"
  })
})


ui <- shinyUI(
  fluidPage(
    titlePanel("Test Connection"),

    sidebarLayout(
      sidebarPanel(
        textInput("drv", "Database Driver", value="postgresql"),
        textInput("user", "User ID"),
        textInput("server", "Server", value="server"),
        textInput("db_name", "Database Name", value="dbName"),
        passwordInput("passwd", "Password"),
        actionButton("connectDB", "Connect to DB")
      ),

      mainPanel(
        textOutput("test")
      )
    )
  )
)

shinyApp(ui=ui, server=server)

1 个答案:

答案 0 :(得分:4)

您知道onSessionEnded变量的session吗?

这是一个非常基本的示例,它为每个用户设置一个随机会话ID,当他们关闭窗口时,会运行一个函数来说明关闭了哪个会话ID。它只是一个概念证明,你可以轻松地为你的数据库量身定制我希望

runApp(shinyApp(
  ui = fluidPage(
    textOutput("sessionId")
  ),
  server = function(input, output, session) {
    sessionId <- as.integer(runif(1, 1, 100000))
    output$sessionId <- renderText(paste0("Session id: ", sessionId))
    session$onSessionEnded(function() {
      cat(paste0("Ended: ", sessionId))
    })
  }
))

修改

Op说他需要变量才能被动反应,所以我认为这是一个可以让他满意的修改

runApp(shinyApp(
  ui = fluidPage(
    textOutput("sessionId")
  ),
  server = function(input, output, session) {
    values <- reactiveValues(sessionId = NULL)
    values$sessionId <- as.integer(runif(1, 1, 100000))
    output$sessionId <- renderText(paste0("Session id: ", values$sessionId))
    session$onSessionEnded(function() {
      observe(cat(paste0("Ended: ", values$sessionId)))
    })
  }
))

免责声明:我不确定将观察结果放在onSessionEnded回调中是否是最佳方法。这有效,但我无法保证其正确性#34;