我有一个闪亮的应用程序,用户应该能够添加,编辑和删除data.frame
的行,因此基于此问题https://community.rstudio.com/t/persistent-data-storage-in-apps-with-multiple-users/1308我选择使用SQLite
数据库存储数据。
我有一个id列,它应该是一个唯一的升序整数。我怎样才能确保这是独一无二的,例如当两个用户同时插入数据时?问题的第二部分是如何在数据库发生变化时检索Shiny中的最新数据?
这是我目前拥有的,它允许读取,添加,删除和编辑行,但不检查ID是否唯一:
library(tibble)
library(RSQLite)
## Create test data.base
db_user <- tibble(
id = c(1, 2),
user = c("markus", "alex")
)
con <- dbConnect(SQLite(), "test.sqlite")
dbWriteTable(con, name = "test", value = db_user, row.names = FALSE, overwrite = TRUE)
dbDisconnect(con)
## -------------------
library(shiny)
library(pool)
library(dplyr)
library(rlang)
library(DBI)
pool <- dbPool(RSQLite::SQLite(),
dbname = "test.sqlite")
ui <- fluidPage(
actionButton("read", "Read data"),
tableOutput("table"),
hr(),
textInput("new.user", "New User"),
numericInput("new.id", "New ID", 1),
actionButton("add", "Add"),
hr(),
numericInput("edit.id", "select id to edit", value = 1),
textInput("edit.user", "Edited User"),
actionButton("edit", "Edit"),
hr(),
numericInput("delete.id", "select id to delete", value = 1),
actionButton("delete", "Delete")
)
server <- function(input, output, session) {
values <- reactiveValues(data = NULL)
observeEvent(input$read, {
values$data <- pool %>%
tbl("test") %>%
collect()
})
output$table <- renderTable({
req(values$data)
values$data
})
observeEvent(input$add, {
#db_insert_into(pool, "test", data.frame(id = input$new.id, user = input$new.user))
dbWriteTable(pool, "test", data.frame(id = input$new.id, user = input$new.user),
append = TRUE, rownames = FALSE)
})
observeEvent(input$edit, {
col <- "id"
entryValues <- data.frame(user = input$edit.user, stringsAsFactors = FALSE)
print(entryValues)
sql <- paste0("UPDATE ?table SET ",
paste0(names(entryValues), " = ?", names(entryValues), collapse = ", "),
" WHERE ", col, " = ?idVal;")
print(sql)
query <- sqlInterpolate(pool, sql, .dots = c(
list(table = "test"),
as_list(entryValues),
list(idVal = as.character(input$edit.id))
))
print(query)
dbExecute(pool, query)
})
observeEvent(input$delete, {
print(input$delete.id)
col <- "id"
sql <- paste0("DELETE FROM ?table WHERE ", col, " IN (",
paste0(input$delete.id, collapse = ", "), ");")
print(sql)
query <- sqlInterpolate(pool, sql, table = "test")
dbExecute(pool, query)
})
}
shinyApp(ui, server)
答案 0 :(得分:1)
我有一个id列,它应该是一个唯一的升序整数。我怎样才能确保这是独一无二的,例如当两个用户同时插入数据时?
如果列定义为?? INTEGER PRIMARY KEY AUTOINCREMENT
,其中??是列名。然后INTEGER PRIMARY KEY
将其设为 rowid 的别名(如果您不已编码WITHOUT ROWID
)。
rowid 将始终是唯一的,通常是升序。
AUTOINCREMENT
强制提升但不一定按1提升。但是,它会以一些额外费用提升。
还有一个限制,即最高id可以是9223372036854775807.如果达到此值,则会遇到SQLITE_FULL异常。
您可能希望阅读SQLite Autoincrement