我是以编程方式获取一堆数据集,其中许多都有愚蠢的名称,以数字开头,并有特殊字符,如减号.因为没有一个数据集特别大,我希望利益R对数据类型做出最好的猜测,我(ab)使用dplyr将这些表转储到SQLite中.
我使用方括号来逃避可怕的表名,但这似乎不起作用.例如:
data(iris)
foo.db <- src_sqlite("foo.sqlite3", create = TRUE)
copy_to(foo.db, df=iris, name="[14m3-n4m3]")
Run Code Online (Sandbox Code Playgroud)
这会导致错误消息:
Error in sqliteSendQuery(conn, statement, bind.data) : error in statement: no such table: 14m3-n4m3
如果我选择一个合理的名称,这是有效的.但是,由于种种原因,我真的很想保留繁琐的名字.我也可以直接从sqlite创建这样一个命名不好的表:
sqlite> create table [14m3-n4m3](foo,bar,baz);
sqlite> .tables
14m3-n4m3
Run Code Online (Sandbox Code Playgroud)
如果没有深入破解,看起来dplyr正在以某种方式处理方括号,这是我无法弄清楚的.我怀疑这是一个错误,但我想先在这里检查,以确保我没有遗漏一些东西.
编辑:我忘了提到我只是将janky名称直接传递给dplyr的情况.这错误如下:
library(dplyr)
data(iris)
foo.db <- src_sqlite("foo.sqlite3", create = TRUE)
copy_to(foo.db, df=iris, name="14M3-N4M3")
Error in sqliteSendQuery(conn, statement, bind.data) :
error in statement: unrecognized token: "14M3"
Run Code Online (Sandbox Code Playgroud)
这是 dplyr 中的一个错误。它仍然存在于当前的 github master 中。正如 @hadley 所指出的,他试图在 dplyr 中转义表名之类的内容来防止此问题。您当前遇到的问题是由于两个函数中缺乏转义引起的。当提供未转义的表名称时(并且使用 完成dplyr::db_create_table),表创建工作正常。但是,向表中插入数据是使用DBI::dbWriteTable不支持奇数表名的方式完成的。如果向此函数提供的表名称已转义,则无法在表列表中找到它(您报告的第一个错误)。如果提供转义,则执行插入的 SQL 在语法上无效。
当表格更新时,第二个问题就出现了。获取字段名称的代码(这次实际上在 dplyr 中)再次无法转义表名称,因为它使用而paste0不是build_sql.
我已经在dplyr 的分支上修复了这两个错误。我还向 @hadley 提出了拉取请求,并就该问题做了注释https://github.com/hadley/dplyr/issues/926。同时,如果您愿意,可以使用它devtools::install_github("NikNakk/dplyr", ref = "sqlite-escape"),然后在修复后恢复到主版本。
顺便说一句,在 SQL 中转义表名(和其他标识符)的正确 SQL-99 方法是使用双引号(请参阅转义列名的 SQL 标准?)。MS Access 使用方括号,而 MySQL 默认使用反引号。根据标准,dplyr 使用双引号。
最后,@RichardScriven 的提案不会普遍适用。例如,select在 R 中是完全有效的名称,但在 SQL 中不是语法上有效的表名称。对于其他保留字也是如此。