R Shiny Database Connection基于actionButton(eventReactive) - >连接在eventReactive之外不存在

时间:2016-02-16 08:53:05

标签: r database oracle shiny

我在eventReactive ShinyApp遇到问题。我希望用户在开始时编写用户名和密码,然后单击actionButton并收到消息“sucessfull connection”。我设法做到没有任何问题,但是当我想使用con来获取使用dbListTables的表的列表时,它会说:Error: object 'con' has not been found,同时使用被动反应对象connectDB()我收到错误:Fehler bei der Auswertung des Argumentes 'conn' bei der Methodenauswahl für Funktion 'dbListTables': Fehler in .getReactiveEnvironment()$currentContext() : Operation not allowed without an active reactive context. (You tried to do something that can only be done from inside a reactive expression or observer.) 我怎样才能使连接正常工作?

我的代码:

    library(ROracle)
    library(shiny)
    library(DT)


    server <- shinyServer(
      function(input, output, session) {

        connectDB <- eventReactive(input$connectDB, {

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

          con <- dbConnect(drv,"xx/K",username=input$user,password=input$passwd) 
          con
        })

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

        tableList <- dbListTables(con,schema="K") #I have tried here to use con and as well reactive object in form of connectDB()
        output$out <- renderPrint(tableList)

        updateSelectizeInput(session, "tabnames", server = TRUE, choices = tableList)

        sqlOutput <- reactive({
          sqlInput <- paste("select * from K.",input$tabnames)
          dbGetQuery(con, sqlInput)
        })

        output$table <- DT::renderDataTable(sqlOutput(), server=TRUE, rownames=FALSE, filter="top", options=list(pageLength=10))

        session$onSessionEnded(function() { dbDisconnect(con) })
      })

    ui_panel <- 
      tabPanel("Test",
               sidebarLayout(
                 sidebarPanel(sidebarPanel(
                   textInput("drv", "Database Driver", value="Oracle"),
                   textInput("user", "User ID"),
                   passwordInput("passwd", "Password"),
                   actionButton("connectDB", "Connect to DB")) 
                 ),
                 mainPanel(
textOutput("test"),
                   selectizeInput("tabnames",label = "server side", choices = NULL),
                   tableOutput("out"),
                   dataTableOutput("table")
                 )
               )
      )


    ui <- shinyUI(navbarPage("Test",ui_panel))

    runApp(list(ui=ui,server=server))

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

这里只是你要做的部分

UI

library(shiny)
shinyUI(navbarPage("Test",
         tabPanel("Test",
                      sidebarLayout(
                                sidebarPanel(
                                  textInput("drv", "Database Driver", value="Oracle"),
                                  textInput("user", "User ID"),
                                  passwordInput("passwd", "Password"),
                                  actionButton("connectDB", "Connect to DB")) ,
                                mainPanel(
                                  textOutput("test"),
                                  uiOutput("tabnames_ui"),
                                  tableOutput("out"),
                                  dataTableOutput("table")
                                ))
                              )
                     ))

服务器

library(ROracle)
library(shiny)

shinyServer(function(input, output, session) {
    con=reactiveValues(cc=NULL)

    observeEvent(input$connectDB,{
      if(input$drv != "Oracle"){
        con$cc="Only 'Oracle' implemented currently"
      }else{
        drv <- dbDriver("Oracle")
        con$cc<- dbConnect(drv,"xx/K",username=input$user,password=input$passwd) 
      }
    })
    observe({
      if(!is.null(con$cc)& is(con$cc,"OraConnection")){ # check if connected
        output$test <- renderText({
          "connection success"
        })
        tableList <-reactive({
            dbListTables(con$cc,schema="K")
        }) 
        output$out <- renderPrint(tableList())

        output$tabnames_ui=renderUI({selectInput("tabnames",label = "server side", choices = tableList())})
      }else if (!is.null(con$cc) ){
        output$test <- renderText({
          con$cc
        })
      }
    })


  session$onSessionEnded(function() { 
    observe({
      if(!is.null(con$cc)& is(con$cc,"OraConnection")){# check if connected
    print(paste0("disconnect ",dbDisconnect(con$cc)))}
  }) 
})

  })