在R shiny中插入SQLite数据库时如何确保唯一ID?

时间:2018-02-10 09:32:52

标签: r sqlite shiny

我有一个闪亮的应用程序,用户应该能够添加,编辑和删除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)

1 个答案:

答案 0 :(得分:1)

我有一个id列,它应该是一个唯一的升序整数。我怎样才能确保这是独一无二的,例如当两个用户同时插入数据时?

如果列定义为?? INTEGER PRIMARY KEY AUTOINCREMENT,其中??是列名。然后INTEGER PRIMARY KEY将其设为 rowid 的别名(如果您已编码WITHOUT ROWID)。

rowid 将始终是唯一的,通常是升序。

AUTOINCREMENT强制提升但不一定按1提升。但是,它会以一些额外费用提升。

还有一个限制,即最高id可以是9223372036854775807.如果达到此值,则会遇到SQLITE_FULL异常。

您可能希望阅读SQLite Autoincrement