I would like to build a shiny app which will allow user to choose the table name from database, and their further plotting etc. I stuck at the point of retrieving the table names from database. I cannot use the tableList which i have created using dbListTables(con,schema="K") as a choice for the selectInput widget. I do not get any error or warning, widget just does not appear at all.
My code:
library(ROracle)
library(shiny)
server <- shinyServer(
function(input, output, session) {
con <- dbConnect(dbDriver("Oracle"),"xxx/K",username="user",password="pwd")
tableList <- dbListTables(con,schema="K")
output$out <- renderPrint(tableList)
df <- data.frame()
quer <- paste("select * from K.", input$tabnames)
df <- data.frame(dbGetQuery(con, quer))
output$table <- renderTable({df})
session$onSessionEnded(function() { dbDisconnect(con) })
})
ui_panel <-
tabPanel("Test",
sidebarLayout(
sidebarPanel(
),
mainPanel(
selectInput("tabnames","tabnames", choices=as.list(tableList)),
tableOutput("out"),
tableOutput("table")
)
)
)
ui <- shinyUI(navbarPage("Test",ui_panel))
runApp(list(ui=ui,server=server))
Thanks for any tipps
[SOLVED] the part for the selectizeInput i solved by placing it on the server side:
library(ROracle)
library(shiny)
library(DT)
server <- shinyServer(
function(input, output, session) {
con <- dbConnect(dbDriver("Oracle"),"xx/K",username="user",password="pwd")
tableList <- dbListTables(con,schema="K")
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(
),
mainPanel(
selectizeInput("tabnames",label = "server side", choices = NULL),
tableOutput("out"),
tableOutput("table")
)
)
)
ui <- shinyUI(navbarPage("Test",ui_panel))
runApp(list(ui=ui,server=server))
I additionally made the reactive SQL query.
Than i choosed the table from selectizeInput to display, [NOT SOLVED] however it shows me an error:
Error in .oci.GetQuery(conn, statement, data = data, prefetch = prefetch, :
ORA-00903: invalid table name
Than smthg has to be wrong with my SQL Query (Thanks for the tipps here!)
How its even possible if i choosed the table name from the dbListTables?
Any ideas?
I have solved my second question! The problem was very small on the side of ui, instead of dataTableOutput, i had tableOutput, so the ui should look like this:
ui_panel <-
tabPanel("Test",
sidebarLayout(
sidebarPanel(
),
mainPanel(
selectizeInput("tabnames",label = "server side", choices = NULL),
tableOutput("out"),
dataTableOutput("table")
)
)
)
Thanks for all the help!
Related
For my first shiny application, I want to load data from sql and display it in a table. This works fine, when I only use text input in the sidePanel menu. I want to display all available databases in a drop-down at first. Next, I want the all schemas for that db displayed in a second drop-down, once the db is chosen. Finally I want to select tables in a drop-down, displayed according to the utilized schema and db.
However, I already run into an error (Error in : invalid connection option "SQLdb"), when I am trying to just select the db via drop-down.
# lib
library(DBI)
library(RPostgres)
library(shiny)
library(dplyr)
library(shinydashboard)
# preload
cc<- dbConnect(RPostgres::Postgres(),
dbname = "postgres",
host = "localhost",
port = "5432",
user="postgres",
password="xxxx")
db_list <- dbGetQuery(cc, "SELECT datname FROM pg_database WHERE datistemplate = FALSE")
db_list <- db_list %>% dplyr::filter(!grepl("postgres", datname))
#### UI --------------------------------------------------------------------------------------------------
ui <- dashboardPage(
dashboardHeader(title = "test"),
dashboardSidebar(
sidebarMenu(
menuItem("Load Data",
tabName = "load_data",
icon = icon("database")
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "load_data",
fluidPage(
sidebarLayout(
sidebarPanel(
#textInput("SQLdb", "Database", value="shiny_data"),
selectInput(inputId = "SQLdb",
label = "Select Database",
choices = db_list,
selected = "shiny_data"),
textInput("schema", "Schema", value="m4_monthly"),
textInput("table", "Table", value="m4_samples"),
textInput("host", "Host", value="localhost"),
textInput("port", "Port", value="5432"),
textInput("user", "User", value = "postgres"),
passwordInput("passwd", "Password"),
actionButton("connectDB", "Load DB table"),
),
mainPanel(
textOutput("test"),
uiOutput("tabnames_ui"),
tableOutput("out"),
dataTableOutput("table")
)))))))
#--------------------------------------------------------------------------------------
#### SERVER
server <- function(input, output, session) {
observe ({
updateSelectInput(session,
"SQLdb",
choices = db_list,
selected = "shiny_data"
)
})
# database load
con=reactiveValues(cc=NULL)
observeEvent(input$connectDB{
con$cc<- dbConnect(RPostgres::Postgres(),
dbname = input$SQLdb,
host = input$host,
port = input$port,
user=input$user,
password=input$passwd)
table_id <- DBI::Id(
schema = input$schema,
table = input$table)
data <- dbReadTable(con$cc, name = table_id, value = input$table)
dbDisconnect(con$cc)
data.frame(data)
output$table <- renderDataTable(data)
})
}
runApp(list(ui = ui, server = server))
i really need your help.
I have an example of a DataBase which table is "t_client (id_cli, name_cli)"
I want to select the id of client(id_cli) from "selectInput" and the result gives me the name of client (name_cli) by reactive function.
This is my code :
req1 = dbGetQuery(DB, "select id_cli, name_cli from t_client;")
selectInput(inputId = "id_cli", label = "Clients", choices = req1$id_cli)
databaseInput <- reactive({
req1$id_cli = input$id_cli
req2 = dbGetQuery(DB, "select *from t_client where id_cli = 'req1$id_cli';")
req2
})
renderTable({
databaseInput()
})
It doesnt work; i dont have the link between the item from selectInput and the real table "t_client"
I noticed if the sidebar menu is created dynamically by the server code, the content doesn't show up when the app loads until after a tab is clicked.
In the example, I used the sample code from the shiny dashboard get started page. The app runs as expected. However, as you can see, I change the sidebar menu to be dynamically created, a blank page shows up when app loads. I have to click on the first tab at the side bar to bring up the page. Is there a way to display a default page, namely the dashboard tab page? Please note I entered an issue on shiny dashboard github page. Thanks much for your help.
`## app.R ##
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(title = "Basic dashboard"),
## Sidebar content
# dashboardSidebar(
# sidebarMenu(
# menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
# menuItem("Widgets", tabName = "widgets", icon = icon("th"))
# )
# ),
dashboardSidebar(width=150, sidebarMenuOutput("sideMenu")
),
dashboardBody(
tabItems(
# First tab content
tabItem(tabName = "dashboard",
fluidRow(
box(plotOutput("plot1", height = 250)),
box(
title = "Controls",
sliderInput("slider", "Number of observations:", 1, 100, 50)
)
)
),
# Second tab content
tabItem(tabName = "widgets",
h2("Widgets tab content")
)
)
)
)
server <- function(input, output, session) {
output$sideMenu <- renderMenu({
sidebarMenu(
menuItem("Dashboard", tabName = "dashboard", icon = icon("dashboard")),
menuItem("Widgets", tabName = "widgets", icon = icon("th"))
)
})
set.seed(122)
histdata <- rnorm(500)
output$plot1 <- renderPlot({
data <- histdata[seq_len(input$slider)]
hist(data)
})
}
shinyApp(ui, server)`
You need to set one of your tabs to be active.
For example:
# First tab content
tabItem(tabName = "dashboard", class = "active",
fluidRow(
box(plotOutput("plot1", height = 250)),
box(
title = "Controls",
sliderInput("slider", "Number of observations:", 1, 100, 50)
)
)
),
I want to add new record to table1 on SQLite
use SQL::Abstract;
my %data = (
id => \'max(id)', # it is doesn't work so which variant is right?
record => 'Something'
);
my $sql = SQL::Abstract->new;
my ($stmt, #bind) = $sql->insert('table1', \%data);
...
my $sth = $dbh->prepare($stmt);
If I used DBIx::Class in Catalyst app I would written like so:
id => $c->model('Model')->get_column('id')->max()
and it will work fine.
So how can I reach the same aim but using just SQL::Abstract which is used in DBIx::Class as well.
Could someone fixed it? Thanks.
This is a piece of code. As you can see, first you need to get the max id+1 and then do the insert command. I have to notice you this is not safe, because in a multi-(user,process,thread) environment, a second process can execute the same code and get race conditions.
But I assume you are just learning the SQL::Abstract api, and that problem doesn't matter
use DBI;
use SQL::Abstract;
#create table TEST(ID integer, NAME varchar);
my $dbh = DBI->connect('dbi:SQLite:dbname=test.db', '', '', {AutoCommit=>1});
my $sql = SQL::Abstract->new;
my($stmt, #bind) = $sql->select("TEST", [ 'max(ID)+1 as ID' ] );
my $sth = $dbh->prepare($stmt);
$sth->execute(#bind);
my ($id) = $sth->fetchrow_array // 1;
print "Select ID: $id", "\n";
$sth->finish;
($stmt, #bind) = $sql->insert("TEST", { ID=>$id, NAME=>"test-name"} );
$sth = $dbh->prepare($stmt);
$sth->execute(#bind);
$dbh->disconnect;
I have a basic MySQL database table People with 3 columns (ID, Name, Distance)
I am trying to output this with PHP as a JSON so my web app can pick it up. I tried using the solution from another answer:
$sth = mysql_query($con,"SELECT * FROM People");
$rows = array();
while($r = mysql_fetch_assoc($sth)) {
$rows[] = $r;
}
print json_encode($rows);
However I am just returning a blank array of [].
Update: Changed to mysqli and added dumps:
$sth = mysqli_query("SELECT * FROM Events",$con);
$rows = array();
var_dump($sth);
while($r = mysqli_fetch_assoc($sth)) {
var_dump($rows);
$rows[] = $r;
}
print json_encode($rows);
Returns:
NULL []
Swap your query and connection in the mysql_query-statement:
$sth = mysql_query("SELECT * FROM People", $con);
Besides that, the mysql-library is deprecated. If you're writing new code consider using mysqli_ or PDO.
Why no mysql_connect ?
var_dump($sth); // check the return of mysql_query()
var_dump($rows); // check the array of mysql_fetch_assoc result
I would check if your query is returning any rows first.
<?php
$rows = array();
array_push($rows, array("name" => "John"));
array_push($rows, array("name" => "Jack"));
array_push($rows, array("name" => "Peter"));
print json_encode($rows);
?>
Produces this output.
[{"name":"John"},{"name":"Jack"},{"name":"Peter"}]
Solved using a combination of answer to get:
$sth = mysqli_query($con,"SELECT * FROM Events");
$datarray = array();
while($row = mysqli_fetch_assoc($sth)) {
$datarray[] = $row;
}
print_r(json_encode($datarray));