Как заставить Shiny Reactivity работать с базой данных SQL?

Хорошо, я изменил скрипт, следуя совету @Pork Chop:

server.R

library(shiny)
library(DT)
library(RMySQL)

con <- dbConnect(MySQL(), user="myuser", host="myhost", dbname="mydb")

shinyServer(function(input, output) { 

                sqlOutput <- reactive({
                    sqlInput <- paste0("select * from mydb.mytable",
                           " where value < ", input$value,
                           ";")
                    dbGetQuery(con, sqlInput)
                })

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

                output$download <- downloadHandler("filtered.data.txt", content = function(file) {
                                           rows <- input$table_rows_all
                                           write.table(sqlOutput()[rows, ], file, sep="\t", quote=FALSE, col.names=TRUE, row.names=FALSE)
                })

})

DataTable теперь работает!

Однако, когда я пытаюсь загрузить отображаемые данные, я получаю файл только с именами столбцов и без данных. Согласно DT docs, input $ table_rows_all должен содержать индексы строк отображаемой таблицы .

Что случилось?


У меня проблемы с реактивностью Shiny и базой данных MySQL.

Короче говоря, я получаю входное значение от пользователя, создаю SQL-запрос, фиксирую результат и отображаю его как DataTable.

Выходные данные можно дополнительно отфильтровать с помощью фильтров столбцов DataTable, и пользователь должен иметь возможность загрузить отфильтрованный набор данных.

server.R

library(shiny)
library(DT)
library(RMySQL)

con <- dbConnect(MySQL(), user="myuser", host="myhost", dbname="mydb")

shinyServer(function(input, output) {


                sqlInput <- reactive({
                    paste0("select * from mydb.mytable",
                           " where value < ", input$value,
                           ";")
                })

                sqlOutput <- reactive({
                    dbGetQuery(con, sqlInput)
                })

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

                output$download <- downloadHandler("filtered.data.txt", content = function(file) {
                                           rows <- input$table_rows_all
                                           write.table(sqlOutput[rows, ], file)
                })

})

Вместо DataTable я получаю такую ​​ошибку:

введите описание изображения здесь

Это работает должным образом, если я вставляю sqlInput и sqlOutput в реактивное выражение в DT::renderDataTable(), но тогда я не могу ссылаться на sqlOutput изнутри downloadHandler() (object 'sqlOutput' not found). Я думал, что это идеальный вариант использования reactive(), но я не могу заставить его работать.

Как лучше всего заставить эту работу работать? Любая помощь очень ценится, спасибо!


person enricoferrero    schedule 16.09.2015    source источник
comment
sqlOutput - это функция, поэтому используйте ее так sqlOutput(), также для получения дополнительной информации просмотрите здесь и здесь   -  person Pork Chop    schedule 16.09.2015
comment
Спасибо! В этом есть смысл. Я отредактировал свой вопрос с продолжением.   -  person enricoferrero    schedule 16.09.2015


Ответы (1)


1. sqlOutput - это функция, поэтому измените ее на sqlOutput().

2. Попробуйте это, обратите внимание, что будет экспортироваться, .csv надеюсь, что все в порядке

output$download <- downloadHandler(filename = function() {paste(Sys.time(), ' Fltered_data.csv', sep='')}, content = function(file) {write.csv(sqlOutput()[input$table_rows_all, ], file, row.names = FALSE)})
person Pork Chop    schedule 16.09.2015
comment
Я принял это, поскольку он отвечает на исходный вопрос. Однако загруженный файл по-прежнему остается пустым и содержит только имена столбцов. Есть идеи, что может быть не так? - person enricoferrero; 16.09.2015