2017-01-06 2 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 not found'오류를 발생시키지 않도록 동적으로 필드를 생성하려면이 스크립트를 업그레이드해야 할 것 같습니다. – sgp667

+0

단일 행에 대해 db를 쿼리하고 일치하도록 열 이름을 설정 하시겠습니까? 테이블의 열 이름을 반환하는 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