Как вставить значения в базу данных SQLite из R.Data? - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь вставить данные в sqlite базу данных из R data.frame, но мне не удалось.

Вот код в R studio, который я использовал.

Итак, есть два цикла, с помощью которых я пытаюсь загрузить все файлы dbf, перечисленные в указанных папках (рабочий каталог). А потом я пытаюсь вставить данные из R data.frame (df[[1]]) в базу данных sqlite (я ее уже создал) с помощью sqldf или dbExecute функций.

В случае dbExecute функция не может прочитать таблицу из R data.frame (в данном случае df[[1]]).

В случае sqldf функция не видит all_banks таблица, созданная ранее в базе данных.

Есть идеи, как решить эту проблему? Спасибо всем.

library(sqldf)
library(DBI)
library(foreign)
library("RSQLite")



setwd("F:~/Data")
con <- dbConnect(RSQLite::SQLite(), dbname = "banks.db")
for(path in c("F:~/123-20190901",
          "F:~/123-20190801")){
  setwd(path)
  ldf <- list()
  listdbf <- dir(pattern = "*.DBF")
  for (k in 1:length(listdbf)){
     ldf[[k]] <- read.dbf(listdbf[k])
     }

  df1 <- ldf[[1]]
  df2 <- ldf[[2]]
  dbExecute(con, "insert into all_banks select DT, REGN, name_b from df1")
  sqldf("insert into all_banks select DT, REGN, name_b from df1")
}
dbDisconnect(con)

Error: no such table: df1
Error: no such table: all_banks

1 Ответ

0 голосов
/ 29 октября 2019

По сути, sqldf и dbExecute - это два разных процесса, в которых первый работает в локальной среде, а второй - во внешней базе данных (хотя и с отмеченными исключениями).

За документы ,

sqldf - это пакет R для запуска операторов SQL на R фреймах данных, оптимизированный для удобства.

Следовательно, sqldf, выполняется на R фреймах данных в локальной среде. По умолчанию sqldf не используется для внесения изменений в постоянную внешнюю базу данных. Технически, он запускает базу данных SQLite в памяти, которая не сохраняется после сеанса R. Следовательно, если all_banks не является фреймом данных в глобальной среде, он не будет распознан sqldf. С учетом вышесказанного, существует расширенный способ использования sqldf с постоянной базой данных SQLite. Но решение ниже, возможно, проще.


Per документы , DBI::dbExecute

Выполняет оператор и возвращает количество затронутых строк.

С первым аргументом:

conn: объект DBIConnection, возвращаемый dbConnect().

Следовательно, dbExecute выполняетсякоманды для внешней базы данных и в пределах ее области действия не используют локальные объекты среды. Следовательно, если df1 не является таблицей в базе данных, она не будет распознана dbExecute.


Solution

ToДля разрешения потребностей в добавлении базы данных просто используйте DBI dbWriteTable, который помещает локальный фрейм данных R во внешнюю таблицу базы данных (при условии одинаковой структуры в обеих конечных точках, если не используется overwrite=TRUE). Такие изменения в таблице останутся постоянными даже после закрытия соединения с базой данных или сеанса R.

dbWriteTable(con, name="all_banks", value=df1, append=TRUE)
...