Persistent storage data in MYSQL database through shinny app

36 Views Asked by At

I have created a shinny app where i can communicate with mysql database and store values through a reactive dataframe where users input values.
First I created a table in the mysql database with sql command. The table has 3 columns (mes, categoria, gasto). Gasto is the column where users input values, the other 2 columns remain with the values i inserted through sql command.
i set up the ui and server so the user inputs values and stores them in the mysql database.
The problem is that the values are not permanently stored. They get to default each time i run the app.

This is how i communicate to the database and get the data from the table i created:

conexion<- dbConnect(RMySQL::MySQL(),
                     dbname="chumanita",
                     port= xxxx,
                     host= "xxx",
                     user= "xxxx",
                     password= "xxxx")

gastos_mensuales <- dbGetQuery(conexion, "SELECT * FROM gastos_mensuales")

dbDisconnect(conexion)

this is the part of the UI related to this part of the project:

tabPanel("Gastos",
                       fluidRow(
                         column(width = 12, align = "center",
                                box(
                                  title = "Ingreso de los gastos mensuales",
                                  width = 12,
                                  solidHeader = TRUE,
                                  status = "primary",
                                  uiOutput("expenseInputs"),
                                  actionButton("submitBtn", "Guardar")
                                )
                         )
                       )
                       )

This is the part of the server that i've computed:

Set database options

  options(mysql = list(
    "host" = "xxx",
    "port" = xxx,
    "user" = "xxx",
    "password" = "xxx"
  ))
  databaseName <- "chumanita"
  table <- "gastos_mensuales"

  
  
  # Reactive dataframe to store input values
  stored_expenses <- reactiveVal(data.frame())
  
  # Function to generate input fields dynamically based on selected months
  output$expenseInputs <- renderUI({
    categories <- c("Impuestos", "IMSS", "Nominas", "Honorarios NF", "Honorarios F", "Reactivos", "Maquila")
    months <- month.name
    inputs <- lapply(months, function(month) {
      category_inputs <- lapply(categories, function(category) {
        tagList(
          numericInput(paste0(category, "_", month), paste(category, "(", month, ")"), value = 0)
        )
      })
      tagList(
        h3(month),
        do.call(tagList, category_inputs)
      )
    })
    do.call(tagList, inputs)
  })
  
  # Function to save data to the database
 saveData <- function(data) {
    # Connect to the database
    db <- dbConnect(RMySQL::MySQL(), dbname = databaseName, host = options()$mysql$host, 
                    port = options()$mysql$port, user = options()$mysql$user, 
                    password = options()$mysql$password)
    
    # Construct the update query
    query <- sprintf(
      "UPDATE %s SET Gasto = %f WHERE Mes = '%s' AND Categoria = '%s'",
      table, 
      data$Gasto,
      data$Mes,
      data$Categoria
    )
    
    # Submit the update query and disconnect
    dbExecute(db, query)
    dbDisconnect(db)
  }
  
  # Function to load data from the database
  loadData <- function() {
    # Connect to the database
    db <- dbConnect(RMySQL::MySQL(), dbname = databaseName, host = options()$mysql$host, 
                    port = options()$mysql$port, user = options()$mysql$user, 
                    password = options()$mysql$password)
    
    # Construct the fetching query
    query <- sprintf("SELECT * FROM %s", table)
    
    # Submit the fetch query and disconnect
    data <- dbGetQuery(db, query)
    dbDisconnect(db)
    
    return(data)
  }
  
  observeEvent(input$submitBtn, {
    # Access the input values for each category and month
   categories <- c("Impuestos", "IMSS", "Nominas", "Honorarios NF", "Honorarios F", "Reactivos", "Maquila")
    for (month in month.name) {
      month_inputs <- lapply(categories, function(category) {
        input_value <- input[[paste0(category, "_", month)]]
        return(data.frame(Mes = month, Categoria = category, Gasto = input_value))
      })
      # Add the new rows to the reactive dataframe
     stored_expenses(rbind(stored_expenses(), do.call(rbind, month_inputs)))
      
      # Save data to the database
     all_inputs <- do.call(rbind, month_inputs)
      for (i in seq_len(nrow(all_inputs))) {
        saveData(all_inputs[i, ])
      }
    }
  })

I've tried setting up

stored_expenses <- reactiveVal(loadData())

But gives me : Warning: Error in rbind: numbers of columns of arguments do not match

0

There are 0 best solutions below