Как вставить значения в базу данных SQLite из R.Data?

Я пытаюсь вставить данные в базу данных 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

person David Bijoyan    schedule 29.10.2019    source источник


Ответы (1)


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

Согласно документам,

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

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


Согласно документам, DBI::dbExecute

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

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

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

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


Решение

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

dbWriteTable(con, name="all_banks", value=df1, append=TRUE)
person Parfait    schedule 29.10.2019