Как сделать запрос к базе данных SQL в приложении глянцевых приложений с использованием реактивного выражения с несколькими входными данными из приложенияIX :: seletctInput () - PullRequest
1 голос
/ 23 апреля 2020

Я (очень) новичок в Блестящем и пытаюсь создать приложение, в котором пользователь может ввести свой выбор одного или нескольких параметров, а затем использовать его для запроса к базе данных SQL. Например, если пользователь выбирает «Дублин» или «Абердин», приложение использует RmySQL::dbReadTable(), чтобы извлечь таблицу с тем же именем из базы данных и вывести ее в таблицу. Если пользователь выбирает «Дублин» и «Абердин», приложение использует DBI::dbGetQuery() для запроса базы данных, чтобы выбрать определенные столбцы из каждой таблицы, а затем соединить их вместе, выводя результат в таблицу.

Я могу заставить его работать, когда выбран только один вариант, но не более одного.

Отсюда Shiny использует только первый элемент selectInput, когда множественное значение = TRUE Я предполагаю, что могу получить доступ к отдельным элементам input$dataset, когда выбрано несколько вариантов выбора.

Посмотрев здесь: Получить значение из реактивного контекста в R блестящий на основе пользовательского ввода Я попытался создать запрос, используя реактивную функцию, а затем использовать его во второй реактивной функции, как показано ниже, но приложение не запускается, и я получаю эту ошибку: Ошибка в (функция (классы, fdef, mtable): невозможно найти унаследованный метод для функции 'dbGetQuery' для подписи '' MySQLConnection "," реактивЭкспр "'

library(shiny)
library(rsconnect)
library(RMySQL)
library(dplyr)
library(DBI)

ui = fluidPage(

  titlePanel("EWAS database"),

  sidebarLayout(

    sidebarPanel(

      selectInput("dataset", "Choose one or more datasets:",
                  choices = c("Dublin", "Aberdeen"), selected = NULL, multiple = TRUE),

      numericInput("obs", "Number of results to view:", 10),

      submitButton("Update View"),

      downloadButton("downloadData", "Download")
    ),

    mainPanel(

      tableOutput("table")

    )
  )
)

server <- function(input, output) {

  conn <- dbConnect(drv = MySQL(), dbname = "EWAS", host = “xxx”,
                    username = “xxx”, password = “xxx”)

  Dublin <- dbReadTable(conn = conn, name = 'Dublin', value = as.data.frame(Dublin))
  Aberdeen <- dbReadTable(conn = conn, name = 'Aberdeen', value = as.data.frame(Aberdeen))


  query <- reactive({paste0("'SELECT ", 
                   input$dataset[1], ".", input$dataset[1], "_id, ",
                   input$dataset[1], ".", input$dataset[1], "_Status_Beta, " ,
                   input$dataset[1], ".", input$dataset[1], "_Status_SE, " ,
                   input$dataset[1], ".", input$dataset[1], "_Status_P, " ,
                   input$dataset[2], ".", input$dataset[2], "_id, " ,
                   input$dataset[2], ".", input$dataset[2], "_Status_Beta, " ,
                   input$dataset[2], ".", input$dataset[2], "_Status_SE, " ,
                   input$dataset[2], ".", input$dataset[2], "_Status_P, " ,
                   "From ", input$dataset[1], " LEFT JOIN ", input$dataset[2],
                   " ON ", input$dataset[1], ".", input$dataset[1], "_id ", "= ",
                   input$dataset[2], ".", input$dataset[2], "_id'")})


  custom <- dbGetQuery(conn = conn, query) 


  datasetInput <- reactive({

    if(identical(input$dataset, "Dublin")){
      Dublin
    } else if (identical(input$dataset, "Aberdeen")){
      Aberdeen
    } else 
      custom



  }) 

  output$table <- renderTable({
    head(datasetInput(), n = input$obs)
  })

  output$downloadData <- downloadHandler(
    filename = function(){
      paste(input$dataset, ".csv", sep = "")
    },
    content = function(file){
      write.csv(datasetInput(), file, row.names = F)
    }
  )


  on.exit(dbDisconnect(conn), add = TRUE)
}


shinyApp(ui = ui, server = server)

Я также попытался поместить запрос непосредственно в реактивную функцию (как показано ниже), и в этом случае приложение запускается, но я получаю: внутренняя ошибка в RS_DBI_getConnection: дескриптор поврежденного соединения.

server <- function(input, output) {

  conn <- dbConnect(drv = MySQL(), dbname = "EWAS", host = “xxx”,
                    username = “xxx”, password = “xxx”)

  Dublin <- dbReadTable(conn = conn, name = 'Dublin', value = as.data.frame(Dublin))
  Aberdeen <- dbReadTable(conn = conn, name = 'Aberdeen', value = as.data.frame(Aberdeen))

datasetInput <- reactive({

    if(identical(input$dataset, "Dublin")){
      Dublin
    } else if (identical(input$dataset, "Aberdeen")){
      Aberdeen
    } else 
      dbGetQuery(conn, paste0("'SELECT ", 
                              input$dataset[1], ".", input$dataset[1], "_id, ",
                              input$dataset[1], ".", input$dataset[1], "_Status_Beta, " ,
                              input$dataset[1], ".", input$dataset[1], "_Status_SE, " ,
                              input$dataset[1], ".", input$dataset[1], "_Status_P, " ,
                              input$dataset[2], ".", input$dataset[2], "_id, " ,
                              input$dataset[2], ".", input$dataset[2], "_Status_Beta, " ,
                              input$dataset[2], ".", input$dataset[2], "_Status_SE, " ,
                              input$dataset[2], ".", input$dataset[2], "_Status_P, " ,
                              "From ", input$dataset[1], " LEFT JOIN ", input$dataset[2],
                              " ON ", input$dataset[1], ".", input$dataset[1], "_id ", "= ",
                              input$dataset[2], ".", input$dataset[2], "_id'"))



  }) 

А также с вариацией ниже ... в соответствии с решением здесь: Как заставить Shiny реактивность работать с SQL базой данных? * 1 021 * но на этот раз приложение не запускается, и я получаю: Ошибка в dbGetQuery (conn = conn, query): объект 'query' не найден.

datasetInput <- reactive({

    query <- paste0("'SELECT ", 
                    input$dataset[1], ".", input$dataset[1], "_id, ",
                    input$dataset[1], ".", input$dataset[1], "_Status_Beta, " ,
                    input$dataset[1], ".", input$dataset[1], "_Status_SE, " ,
                    input$dataset[1], ".", input$dataset[1], "_Status_P, " ,
                    input$dataset[2], ".", input$dataset[2], "_id, " ,
                    input$dataset[2], ".", input$dataset[2], "_Status_Beta, " ,
                    input$dataset[2], ".", input$dataset[2], "_Status_SE, " ,
                    input$dataset[2], ".", input$dataset[2], "_Status_P, " ,
                    "From ", input$dataset[1], " LEFT JOIN ", input$dataset[2],
                    " ON ", input$dataset[1], ".", input$dataset[1], "_id ", "= ",
                    input$dataset[2], ".", input$dataset[2], "_id'")

    if(identical(input$dataset, "Dublin")){
      Dublin
    } else if (identical(input$dataset, "Aberdeen")){
      Aberdeen
    } else 
      dbGetQuery(conn, query)


  }) 

Я также думал, что, возможно, смогу получить несколько таблиц по отдельности, затем используйте что-то вроде base::cbind() их вместе, используя только те столбцы, которые я хочу, но я не могу понять, как мне заставить это работать в этом контексте.

Наконец, я необходимо расширить приложение, включив в него множество других таблиц и, в конечном итоге, у пользователя может быть выбрано до 3 опций с чем-то вроде:

    if(length(input$dataset) == 1){
    dbReadTable(conn, name = ‘input$dataset’, value = as.data.frame(input$dataset)
    } else if (length(input$dataset) == 2){
      dbGetQuery(conn, query2)
    } else if (length(input$dataset) == 3){
      dbGetQuery(conn, query3)
}

, поэтому я действительно надеюсь, что любое решение поможет принять это во внимание. Буду очень признателен за любую помощь или совет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...