Abh*_*ute 5 r unique-constraint rmysql shiny r-dbi
我正在使用DBI,RMySql包与数据库交互MySql。
以下是有关配置的更多详细信息:
以下是表 Site 的架构:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| short_name | varchar(10) | NO | UNI | NULL | |
| full_name | varchar(50) | NO | UNI | NULL | |
+------------+-------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,字段short_name&full_name具有UNIQUE&NOT NULL约束。
在尝试插入具有重复项short_name或full_name表中已存在的行时,dbWriteTable不会发生此类行插入,但它会返回状态TRUE,即使它违反了UNIQUE约束。对于约束也会发生同样的情况NOT NULL。
DBI这是&的预期行为吗dbWriteTable?为什么它不返回FALSE状态?
编辑:我还观察到,即使在违反约束的情况下dbSendStatement(),也dbSendQuery()不会给出任何错误。有什么办法可以了解这个吗?
我觉得必须有更好的方法来做到这一点,但我知道的解决方案是使用 tryCatch 来捕获错误消息。除了捕获消息之外,还有其他选项......例如,您可以采取行动。
文档中解释了 dbWriteTable 不返回 FALSE 的原因。仅当 DBI 函数出现问题时,它才会返回 FALSE。你的问题出在数据库上。我知道这是语义,但它在这里有所不同。
我编了一个例子,因为我没有从问题中得到一个例子。
library(DBI)
library(RSQLite)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
dbSendQuery(con,
"CREATE TABLE mtcars
(
mpg REAL,
cyl INTEGER,
disp REAL,
hp REAL,
drat REAL NOT NULL
);")
dbWriteTable(con, "mtcars", mtcars[1:5,1:5], append = TRUE)
test_db <- dbGetQuery(con,"SELECT * FROM mtcars")
test_db
# mpg cyl disp hp drat
# 1 21.0 6 160 110 3.90
# 2 21.0 6 160 110 3.90
# 3 22.8 4 108 93 3.85
# 4 21.4 6 258 110 3.08
# 5 18.7 8 360 175 3.15
# Can't capture output
result <- dbWriteTable(con, "mtcars",
data.frame(mpg = 1, cyl = 2, disp = 3, hp = 4, drat = NA),
append = TRUE)
result
# Error: object 'result' not found
# Let's try checking exceptions
# This doesn't work because it is checking for exceptions in the DBI commands...not in the database.
result <- dbGetException(con)
result
# $errorNum
# [1] 0
#
# $errorMsg
# [1] "OK"
# Because of the error there wasn't a change in the database.
test_db <- dbGetQuery(con,"SELECT * FROM mtcars")
test_db
# mpg cyl disp hp drat
# 1 21.0 6 160 110 3.90
# 2 21.0 6 160 110 3.90
# 3 22.8 4 108 93 3.85
# 4 21.4 6 258 110 3.08
# 5 18.7 8 360 175 3.15
# We can use a tryCatch to capture error or warning messages
tryCatch({
dbWriteTable(con, "mtcars",
data.frame(mpg = 1, cyl = 2, disp = 3, hp = 4, drat = NA),
append = TRUE)
result <- dbGetException(con)
},
error = function(e) result <<- conditionMessage(e),
warning = function(w) result <<- conditionMessage(w)
)
Run Code Online (Sandbox Code Playgroud)