首页 > 解决方案 > 如何从 R.Data 向 SQLite 数据库插入值?

问题描述

我正在尝试将数据sqlite从 R 插入数据库,data.frame但我失败了。

这是我使用的 R studio 中的代码。

所以有两个循环,我试图加载dbf指定文件夹(工作目录)中列出的所有文件。然后我试图通过函数或函数将数据从 R data.frame( df[[1]])插入sqlite数据库(我已经创建它)。sqldfdbExecute

如果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

标签: sqlrdatabasersqlite

解决方案


从根本上说,sqldfdbExecute是两个不同的过程,前者在本地环境中工作,后者在外部数据库中工作(尽管有一些例外)。

根据文档

sqldf 是一个 R 包,用于在 R 数据帧上运行 SQL 语句,为方便起见进行了优化。

因此,sqldf, 在本地环境中的 R 数据帧上运行。默认情况下,sqldf不用于对持久的外部数据库进行更改。从技术上讲,它运行一个内存中的 SQLite 数据库,该数据库在 R 会话后不保存。因此,如果all_banks不是全局环境中的数据框,它将不会被sqldf. 话虽如此,有一种使用永久 SQLite 数据库的高级方法。sqldf但下面的解决方案可以说更容易。


根据文档DBI::dbExecute

执行一条语句并返回受影响的行数。

第一个论点:

conn: 一个 DBIConnection 对象,由 . 返回dbConnect()

因此,在外部dbExecute数据库上运行命令并在其范围内不使用本地环境对象。因此,如果df1不是数据库中的表,它将不会被.dbExecute


解决方案

要解决您的数据库追加需求,只需使用 DBIdbWriteTable将本地 R 数据帧推送到外部数据库表中(假设两个端点的结构相同,除非使用overwrite=TRUE)。即使在关闭数据库连接或 R 会话后,对表的此类更改仍将保持不变。

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

推荐阅读