2017-01-06 31 views
0

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

我使用该函数导入了很多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")})

+0

目前还不清楚你在这里做什么。您是否试图跳过关于命名'source.df'列的部分?或者你在谈论脚本的'dbWriteTable'部分? – Abdou

+0

我想要升级这个脚本来动态创建字段,使'dbWriteTable'不会引发错误'找不到列Columns NewColumn'。 – sgp667

+0

查询数据库的单行,并设置列名称以匹配?我必须查看文档,看看是否有一个DBI函数用于返回表的列名... – joran

回答

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) 

我希望它服务一个目的。

+0

作品很有魅力,谢谢 – sgp667