我以编程方式获取了一堆数据集,其中许多数据集都有愚蠢的名称,以数字开头,并有特殊字符,如减号。因为没有一个数据集特别大,我希望利益R对数据类型做出最好的猜测,我使用dplyr将这些表转储到SQLite中。
我使用方括号来逃避可怕的表名,但这似乎不起作用。例如:
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: no such table: 14m3-n4m3
如果我选择一个明智的名字,这是有效的。但是,由于各种原因,我真的很想保留繁琐的名字。我也可以直接从sqlite创建这样一个命名不好的表:
sqlite> create table [14m3-n4m3](foo,bar,baz);
sqlite> .tables
14m3-n4m3
如果没有深入剖析事物,这看起来像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"
答案 0 :(得分:3)
这是dplyr中的一个错误。它仍然存在于当前的github主服务器中。正如@hadley指出的那样,他试图逃避dplyr中的表名等事情来防止这个问题。您当前遇到的问题是由于两个功能中缺少转义而引起的。在提供未转义的表名(并使用dplyr::db_create_table
完成)时,表创建工作正常。但是,使用DBI::dbWriteTable
完成向表中插入数据,paste0
不支持奇数表名。如果表名被提供给此函数转义,则无法在表列表中找到它(您报告的第一个错误)。如果提供了转义,则执行插入的SQL不会在同义上有效。
第二个问题出现在表格更新时。获取字段名称的代码(这次实际上在dplyr中)再次无法转义表名,因为它使用build_sql
而不是devtools::install_github("NikNakk/dplyr", ref = "sqlite-escape")
。
我已在a fork of dplyr处修复了这两个错误。我还向@hadley提出了拉取请求,并就问题https://github.com/hadley/dplyr/issues/926做了说明。与此同时,如果您愿意,可以使用select
,然后在修复后恢复为主版本。
顺便说一下,在SQL中转义表名(和其他标识符)的正确SQL-99方法是双引号(参见SQL standard to escape column names?)。 MS Access使用方括号,而MySQL默认使用反引号。根据标准,dplyr使用双引号。
最后,来自@RichardScriven的提案不会普遍起作用。例如,\r
在R中是完全有效的名称,但在SQL中不是语法上有效的表名。其他保留字也是如此。