I'm building a shiny app where the user could update a table in a database by editing a selected row in a DT:table.
The problem is that process can be time-consuming when the dt:table has many columns (let's say 25 for instance). So I was wondering if there was a nice and efficient way to link my "vals" variables in the query below with the dataframe columns ?
The code below is working but since my DT:table has more than 60 columns I really cannot stick to this solution... :(
selected_row <- donnees[input$dt_rows_selected,]
query <- glue_sql('UPDATE myschema.mytable SET field1= ({vals*}), field2= ({vals2*}), field3 = ({vals3*}), field4= ({vals4*}), field5= ({vals5*}) WHERE id IN ({ID_field*});',
vals = selected_row$column1, vals2 = selected_row$column2, vals3= selected_row$column3, vals4= selected_row$column4, vals5= selected_row$column5, ID_field= selected_row$ID, .con = pool)
DBI::dbExecute(pool2, query)
CodePudding user response:
The purpose of this answer is two-fold:
- Demonstrate the (a?) proper postgres-style upsert action. I present a
pg_upsertfunction, and in that function I've included (prefixed with#'#) what the query looks like when finished. The query is formed dynamically, so does not need a priori knowledge of the fields other than the user-providedidfields=argument. - Demonstrate how to react to
DT-edits using this function. This is one way and there are definitely other ways to formulate how to deal with the reactiveDT. If you have a different style for keeping track of changes in theDT, then feel free to takepg_upsertand run with it!
Notes:
it does not update the database with each cell edit, the changes are "batched" until the user clicks the
Upsert!button; it is feasible to change to "upsert on each cell", but that would be a relatively trivial query, no need for upsertssince you're using postgres, the target table must have one or more unique indices (see

