带 dplyr 的括号转义 table 名称

Bracket-escaped table names with dplyr

我正在以编程方式获取一堆数据集,其中许多都有以数字开头的愚蠢名称,并且其中包含减号等特殊字符。因为 none 的数据集特别大,我希望 R 能够对数据类型做出最好的猜测,所以我(ab)使用 dplyr 将这些 table 转储到 SQLite 中。

我正在使用方括号来转义可怕的 table 名称,但这似乎不起作用。例如:

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 创建这样一个名字不好的 table:

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"

这是 dplyr 中的错误。它仍然存在于当前的 github 母版中。正如@hadley 指出的那样,他试图在 dplyr 中转义 table 名称之类的东西以防止出现此问题。您当前遇到的问题是由于两个函数中没有转义而引起的。当提供未转义的 table 名称时,Table 创建工作正常(使用 dplyr::db_create_table 完成)。但是,向 table 插入数据是使用不支持奇数 table 名称的 DBI::dbWriteTable 完成的。如果将 table 名称提供给此转义函数,则无法在 table 列表中找到它(您报告的第一个错误)。如果提供转义,则执行插入的 SQL 在句法上无效。

第二个问题在 table 更新时出现。获取字段名称的代码,这次实际上是在 dplyr 中,再次无法转义 table 名称,因为它使用 paste0 而不是 build_sql.

我已经修复了 a fork of dplyr. I've also put in a pull request to @hadley and made a note on the issue https://github.com/hadley/dplyr/issues/926 中的两个错误。同时,如果您愿意,可以使用 devtools::install_github("NikNakk/dplyr", ref = "sqlite-escape"),然后在修复后恢复到主版本。

顺便说一句,在 SQL 中转义 table 名称(和其他标识符)的正确 SQL-99 方法是使用双引号(参见 SQL standard to escape column names?)。 MS Access 使用方括号,而 MySQL 默认为反引号。 dplyr 按照标准使用双引号。

最后,@RichardScriven 的提议不会普遍适用。例如,select 在 R 中是完全有效的名称,但在 SQL 中不是语法上有效的 table 名称。其他保留字也是如此。