DBI dbWriteTable

时间:2017-01-06 19:46:05

标签: sql r

我非常喜欢DBI的dbWriteTable函数(我通常使用RSQLite或ROracle作为后端)。

我使用该功能导入了大量excel电子表格,问题是如果这些电子表格是通过长期列创建的,则会添加/删除更改或将名称从一个文档更改为另一个文档。

所以我的问题是,是否有人能够以相对快捷的方式将数据添加到数据库而无需完全匹配归档列表?

以下是我使用的示例脚本

require(RSQLite)
require(readxl)

# Create database file
conn <- dbConnect(drv=SQLite(),dbname = "path to database")

# Define import function

excel2sqltable <- function(conn, file, table) {
  source.df <-  read_excel(path=file,col_names = TRUE) %>%
  cbind("SourceFile" = file, .)

  names(source.df) <- source.df %>%
    data.frame(check.names = TRUE) %>%
    {gsub("[.]",x=names(.),replacement="_")}

  print(paste("Importing ", file))

  setOldClass(c("tbl_df", "data.frame"))
  dbWriteTable(conn = conn, name = table, value = source.df, append=TRUE)
}

使用该功能,我可以:    sapply(list.files(),FUN = function(x){excel2sqltable(conn,x,"Imports")})

1 个答案:

答案 0 :(得分:1)

您可以将此作为指南:

library(RSQLite)

sqlite_conn <- dbConnect(drv = SQLite(),dbname = 'data_dump.sqlite')

excel2sqltable <- function(conn, file, table) {
  source.df <-  readxl::read_excel(path=file,col_names = TRUE) %>%
    cbind("SourceFile" = file, .)

  names(source.df) <- source.df %>%
    data.frame(check.names = TRUE) %>%
    {gsub("[.]",x=names(.),replacement="_")}

  if(!dbExistsTable(conn, table)) {
    dbWriteTable(conn = conn, name = table, value = source.df)
  } else {
    # Get both dataframe columns and table columns
    df_cols <- colnames(source.df)
    tbl_cols <- dbListFields(conn, table)

    # Check if there are columns in the dataframe
    # that are not in the destination table
    # Loop through the missing columns and add
    # them to the database table
    if (length(setdiff(df_cols, tbl_cols)) > 0) {
      missing_cols <- setdiff(df_cols, tbl_cols)
      for (col_name in missing_cols) {
        dbSendStatement(conn, sprintf('ALTER TABLE %s ADD %s VARCHAR', table, col_name))
      }
    }

    setOldClass(c("tbl_df", "data.frame"))


    dbWriteTable(conn = conn, name = table, value = source.df, append=TRUE)
  }
}

lapply(list.files(), function(x) {
  excel2sqltable(sqlite_conn, x, "Imports")
})
dbDisconnect(sqlite_conn)

我希望它有用。