2017-01-06 6 views
4

Недавно я обновил R, RSQLite и sqldf (версии ниже).sqldf: создать таблицу из ошибки фрейма данных: «нет такой таблицы». и две таблицы созданы вместо одного

Обычно:

sqldf('create table foo as select * from bar', db = 'test.db') 

необходимо создать таблицу с именем «Foo» в присоединенной базе данных SQLite, используя кадр данных «бар», если он существует, чтобы загрузить новую таблицу.

Вместо этого я получаю ошибку «нет такой таблицы», а также когда я смотрю на базу данных, создаются таблицы «foo» и «bar».

Возпроизводимо пример:

library(RSQLite) 
library(sqldf) 
mydb = 'test.db' 
## remove file if it exists                                              
system(paste('rm', mydb)) 
## open connection                                                 
##con <- dbConnect(SQLite(), dbname=mydb)                                           
system(paste('ls -l', mydb)) 
sqldf(paste0('attach "', mydb, '" as new')) 
system(paste('ls -l', mydb)) 
class(mtcars) 
sqldf('create table mycars as select * from mtcars', dbname = mydb) 
sqldf('select * from sqlite_master', dbname = mydb) 
sqldf('select * from main.mycars limit 1', dbname = mydb) 
sqldf('select * from main.mtcars limit 1', dbname = mydb) 
sessionInfo() 

, который производит две таблицы и выдает ошибку (в довершение):

> library(RSQLite)                                                
    > library(sqldf)                                                 
    Loading required package: gsubfn 
    Loading required package: proto 
    > mydb = 'test.db'                                                
    > ## remove file if it exists                                              
    > system(paste('rm', mydb))                                              
    > ## open connection                                                
    > ##con <- dbConnect(SQLite(), dbname=mydb)                                          
    > system(paste('ls -l', mydb))                                             
    ls: test.db: No such file or directory 
    > sqldf(paste0('attach "', mydb, '" as new'))                                         
    Loading required package: tcltk 
    data frame with 0 columns and 0 rows 
    > system(paste('ls -l', mydb))                                             
    -rwxrwxrwx 1 nathan staff 1 Jan 6 10:01 test.db 
    > class(mtcars)                                                 
    [1] "data.frame" 
    > sqldf('create table mycars as select * from mtcars', dbname = mydb)                                   
    Error in rsqlite_send_query([email protected], statement) : 
     no such table: `mtcars` 
    In addition: Warning message: 
    Quoted identifiers should have class SQL, use DBI::SQL() if the caller performs the quoting. 
    > sqldf('select * from sqlite_master', dbname = mydb)                                        
     type name tbl_name rootpage 
    1 table mtcars mtcars  2 
    2 table mycars mycars  5 
                                                    sql 
    1 CREATE TABLE `mtcars` (\n "mpg" REAL,\n "cyl" REAL,\n "disp" REAL,\n "hp" REAL,\n "drat" REAL,\n "wt" REAL,\n "qsec" REAL,\n "vs" REAL,\n "am" REAL,\n "gear" REAL,\n "carb" REAL\n) 
    2       CREATE TABLE mycars(\n mpg REAL,\n cyl REAL,\n disp REAL,\n hp REAL,\n drat REAL,\n wt REAL,\n qsec REAL,\n vs REAL,\n am REAL,\n gear REAL,\n carb REAL\n) 
    > sqldf('select * from main.mycars limit 1', dbname = mydb)                                      
     mpg cyl disp hp drat wt qsec vs am gear carb 
    1 21 6 160 110 3.9 2.62 16.46 0 1 4 4 
    > sqldf('select * from main.mtcars limit 1', dbname = mydb)                                      
     mpg cyl disp hp drat wt qsec vs am gear carb 
    1 21 6 160 110 3.9 2.62 16.46 0 1 4 4 
    > sessionInfo()                                                 
    R version 3.3.2 (2016-10-31) 
    Platform: x86_64-apple-darwin13.4.0 (64-bit) 
    Running under: OS X El Capitan 10.11.6 

    locale: 
    [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 

    attached base packages: 
    [1] tcltk  stats  graphics grDevices utils  datasets methods base 

    other attached packages: 
    [1] sqldf_0.4-10 gsubfn_0.6-6 proto_1.0.0  RSQLite_1.1-1 devtools_1.12.0 

    loaded via a namespace (and not attached): 
    [1] DBI_0.5-1  withr_1.0.2 Rcpp_0.12.8 memoise_1.0.0 digest_0.6.11 chron_2.3-48 

Is this a bug or some new intended behavior? Thanks for your help. 
+0

Возможно, вы смешиваете среды (R vs SQLite). Почему бы не использовать 'dbWriteTable()' RSQLite и оставить 'sqldf()' только для управления R dfs? – Parfait

+2

Недавно был выпущен RSLQite 1.1-1, и я подозреваю, что он ввел некоторую несовместимость с существующим программным обеспечением. Предложите вам вернуться к RSQLite 1.0.0: 'devtools :: install_url (" https://cran.r-project.org/src/contrib/Archive/RSQLite/RSQLite_1.0.0.tar.gz ")' –

+1

@G .Grothendieck: '? DbWriteTable' и'? DbRemoveTable' говорит, что 'name' является символьной строкой [a] с указанием имени таблицы СУБД", в ней говорится, что имя 'name' должно быть процитировано, вот что означает' sqldf' делать внутренне. Я бы сказал, что sqldf работает вне спецификации здесь. Тем не менее, я очень скоро выпущу RSQLite 1.1-2, чтобы улучшить совместимость sqldf. – krlmlr

ответ

4

UPDATE: новые версии RSQLite и sqldf нет проблемы несовместимости, устраняемые этим вопросом т.е.: sqldf_0.4-10 RSQLite_1.1-2 хорошо работают вместе - Nathan

Все: Спасибо Г. Гротендику за указатели на проблемы несовместимости, представленные RSQLite 1.1-1. Как указано в комментарии к ответу, понижаем RSQLite в версии 1.0.0:

devtools::install_url("https://cran.r-project.org/src/contrib/Archive/RSQLite/RSQLite_1.0.0.tar.gz") 
+2

Я считаю, что комментарий, который я представил на вопрос, был правильным, но вышеизложенное изменило совет и было не так, поэтому я отредактировал ответ. Вы НЕ хотите переустанавливать 'sqldf', и особенно вы НЕ хотите устанавливать старую версию' sqldf'.Проблема была введена RSQLite 1.1-1, и это единственный пакет, который вам нужно откат. Если вы еще не установили 'sqldf', просто установите его обычным способом, используя' install.packages («sqldf») ', убедившись, что вы это сделаете ДО того, как вы это делаете. (Также я удалил строку 'library (devtools)' как избыточную.) –

+0

Спасибо, вы правы. Установка sqldf после RSQLite перезапишет версию 1.0.0, что заставило меня сбиться с пути. Установка обновленного sqldf с последующей установкой RSQLite 1.0.0 проходит пример теста. Еще раз спасибо. –

+0

Я открыл связанный поток здесь https://unix.stackexchange.com/q/372927/16920, чтобы сохранить строго RSQLite 1.0.0 в вашей системе, потому что я столкнулся с этой проблемой из-за обновлений, поступающих в систему, а также обновления RSQLite , так что снова сломайте настройку. –

2

Это действительно проблема совместимости между текущей версией RSQLite и sqldf пакета. RSQLite теперь более строг относительно аргументов, которые он принимает для dbReadTable(), dbWriteTable() и dbRemoveTable(), предупреждения будут выдаваться (но только один раз за сеанс) до тех пор, пока не будет адаптирован sqldf.

В ближайшее время я выпущу обновление совместимости, будет issue on GitHub, который будет содержать обновления прогресса.

+1

Знаете ли вы, когда это выходит? Я думаю, что он еще не выпущен, потому что у меня такая же проблема. –

+1

К сожалению, нет. – krlmlr