Подтвердить что ты не робот

Названия таблиц с экранированными скобками с dplyr

Я программно собираю кучу наборов данных, у многих из них есть глупые имена, которые начинаются с цифр и имеют в них специальные символы, такие как минусовые знаки. Поскольку ни один из наборов данных не является особенно большим, и я хотел, чтобы преимущество R делало все возможное для описания типов данных, я (ab), используя 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 обрабатывает квадратные скобки каким-то образом, что я не могу понять. Мое подозрение в том, что это ошибка, но я хотел сначала проверить здесь, чтобы убедиться, что я ничего не пропустил.

EDIT: Я забыл упомянуть случай, когда я просто передаю 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"
4b9b3361

Ответ 1

Это ошибка в dplyr. Он все еще там в нынешнем хозяине github. Как указывает @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-99 способ избежать имен таблиц (и других идентификаторов) в SQL с двойными кавычками (см. SQL-стандарт для удаления имен столбцов?), MS Access использует квадратные скобки, а MySQL по умолчанию - обратные. dplyr использует двойные кавычки по стандарту.

Наконец, предложение от @RichardScriven не будет работать повсеместно. Например, select является вполне допустимым именем в R, но не является синтаксически допустимым именем таблицы в SQL. То же самое можно сказать и о других зарезервированных словах.