在连接到 PostgreSQL 的 Shiny 应用程序中设置数据刷新
Setting up data refreshing in Shiny app connected to PostgreSQL
我查看了 this and this 线程和其他一些线程,但未能找到我的解决方案。
我已经使用 R 和 Shiny 构建了一个仪表板,并且说仪表板使用 RPostgreSQL
包从 Postgres 数据库中提取数据。现在,所有数据拉取和分析的代码都在 shinyServer
函数之外完成,只有显示部分( output
和 render
函数)在 shinyServer
部分。我想对其进行设置,以便定期刷新仪表板数据并更新图表。我研究了 reactivePoll
和 invalidateLater
并理解了它们,但不太清楚如何在我的代码中实现它。
这是一个简化的例子server.R
代码:
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host='host', port='12345', dbname='mydb',
user='me', password='mypass')
myQuery <- "select * from table"
myTable <- dbGetQuery(con, myQuery)
foo <- nrow(myTable)
bar <- foo * 2
shinyServer(
function(input, output, session) {
output$foo <- renderText(foo)
output$bar <- renderText(bar)
session$onSessionEnded(function(){
dbDisconnect(con)
dbDisconnect(con2)
dbUnloadDriver(drv)
})
}
)
现在,如果我希望 foo
定期更新,则需要我刷新我也有的 dbGetQuery
命令,但我不知道如何让它们一起工作。我是否需要重新格式化并将所有内容放入 shinyServer
函数中?我有大约 250 行代码,把它们全部扔进去感觉不对,只是把数据拉取部分放在那里可能会打乱事物的顺序。任何帮助表示赞赏。
我会使用 reactivePoll
而不是 invalidateLater
,因为它只会在有新数据的情况下重新获取整个数据。
然而,没有办法将获取数据的代码放入 shinyServer
,因为您的后续计算取决于(反应性)数据。
免责声明:我没有任何使用 SQL 的经验,由于缺乏合适的数据库,我无法测试我的代码,但根据我的理解shiny
以下代码应该有效。
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host='host', port='12345', dbname='mydb',
user='me', password='mypass')
check_for_update <- function() {
dbGetQuery(con, "SELECT MAX(timestamp) FROM table") # edit this part in case
# the syntax is wrong. the goal is to create an identifier which changes
# when the underlying data changes
}
get_data <- function() {
dbGetQuery(con, "select * from table")
}
close_connection <- function() {
dbDisconnect(con)
dbUnloadDriver(drv)
}
shinyServer(
function(input, output, session) {
# checks for new data every 10 seconds
data <- reactivePoll(10000, session,
checkFunc = check_for_update,
valueFunc = get_data)
# the outputs will only be refreshed in case the data changed
output$foo <- renderText({
nrow(data())
})
output$bar <- renderText({
bar <- data() * 2
})
session$onSessionEnded(close_connection)
}
)
根据您应用的结构,将计算封装到一个单独的 reactive
中可能会有所帮助,您可以在多个地方重复使用它。
可以在此 tutorial.
中找到有关使用 shinyApps 执行代码的一些说明
如果您 运行 遇到任何问题,请发表评论,我会尝试相应地更新我的 post。
我查看了 this and this 线程和其他一些线程,但未能找到我的解决方案。
我已经使用 R 和 Shiny 构建了一个仪表板,并且说仪表板使用 RPostgreSQL
包从 Postgres 数据库中提取数据。现在,所有数据拉取和分析的代码都在 shinyServer
函数之外完成,只有显示部分( output
和 render
函数)在 shinyServer
部分。我想对其进行设置,以便定期刷新仪表板数据并更新图表。我研究了 reactivePoll
和 invalidateLater
并理解了它们,但不太清楚如何在我的代码中实现它。
这是一个简化的例子server.R
代码:
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host='host', port='12345', dbname='mydb',
user='me', password='mypass')
myQuery <- "select * from table"
myTable <- dbGetQuery(con, myQuery)
foo <- nrow(myTable)
bar <- foo * 2
shinyServer(
function(input, output, session) {
output$foo <- renderText(foo)
output$bar <- renderText(bar)
session$onSessionEnded(function(){
dbDisconnect(con)
dbDisconnect(con2)
dbUnloadDriver(drv)
})
}
)
现在,如果我希望 foo
定期更新,则需要我刷新我也有的 dbGetQuery
命令,但我不知道如何让它们一起工作。我是否需要重新格式化并将所有内容放入 shinyServer
函数中?我有大约 250 行代码,把它们全部扔进去感觉不对,只是把数据拉取部分放在那里可能会打乱事物的顺序。任何帮助表示赞赏。
我会使用 reactivePoll
而不是 invalidateLater
,因为它只会在有新数据的情况下重新获取整个数据。
然而,没有办法将获取数据的代码放入 shinyServer
,因为您的后续计算取决于(反应性)数据。
免责声明:我没有任何使用 SQL 的经验,由于缺乏合适的数据库,我无法测试我的代码,但根据我的理解shiny
以下代码应该有效。
library(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, host='host', port='12345', dbname='mydb',
user='me', password='mypass')
check_for_update <- function() {
dbGetQuery(con, "SELECT MAX(timestamp) FROM table") # edit this part in case
# the syntax is wrong. the goal is to create an identifier which changes
# when the underlying data changes
}
get_data <- function() {
dbGetQuery(con, "select * from table")
}
close_connection <- function() {
dbDisconnect(con)
dbUnloadDriver(drv)
}
shinyServer(
function(input, output, session) {
# checks for new data every 10 seconds
data <- reactivePoll(10000, session,
checkFunc = check_for_update,
valueFunc = get_data)
# the outputs will only be refreshed in case the data changed
output$foo <- renderText({
nrow(data())
})
output$bar <- renderText({
bar <- data() * 2
})
session$onSessionEnded(close_connection)
}
)
根据您应用的结构,将计算封装到一个单独的 reactive
中可能会有所帮助,您可以在多个地方重复使用它。
可以在此 tutorial.
中找到有关使用 shinyApps 执行代码的一些说明如果您 运行 遇到任何问题,请发表评论,我会尝试相应地更新我的 post。