簡體   English   中英

使用 r 將多個 csv 文件導入 postgresql 數據庫(內存錯誤)

[英]Import multiple csv files into postgresql database using r (memory error)

我正在嘗試將數據集(包含許多 csv 文件)導入 r,然后將數據寫入 postgresql 數據庫中的表中。

我成功連接到數據庫,創建了一個循環來導入 csv 文件並嘗試導入。 R 然后返回錯誤,因為我的電腦用完了 memory。

我的問題是:有沒有辦法創建一個循環,一個接一個地導入文件,將它們寫入 postgresql 表並在之后刪除它們? 這樣我就不會用完 memory。

返回 memory 錯誤的代碼:

`#connect to PostgreSQL database
db_tankdata <- 'tankdaten'  
host_db <- 'localhost'
db_port <- '5432'
db_user <- 'postgres'  
db_password <- 'xxx'
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname = db_tankdata, host=host_db, 
                 port=db_port, user=db_user, password=db_password)

#check if connection was succesfull
dbExistsTable(con, "prices")

#create function to load multiple csv files
import_csvfiles <- function(path){
  files <- list.files(path, pattern = "*.csv",recursive = TRUE, full.names = TRUE)
  lapply(files,read_csv) %>% bind_rows() %>% as.data.frame()
    }


#import files
prices <- import_csvfiles("path...")
dbWriteTable(con, "prices", prices , append = TRUE, row.names = FALSE)`

提前感謝您的反饋!

如果更改lapply()以包含匿名 function,則可以讀取每個文件並將其寫入數據庫,從而減少所需的 memory 數量。 由於lapply()充當隱含for()循環,因此您不需要額外的循環機制。

import_csvfiles <- function(path){
     files <- list.files(path, pattern = "*.csv",recursive = TRUE, full.names = TRUE)
     lapply(files,function(x){ 
          prices <- read.csv(x) 
          dbWriteTable(con, "prices", prices , append = TRUE, row.names = FALSE)
          })
}

我假設您要導入數據庫的 csv 文件非常大? 據我所知,R 首先要使用您編寫的代碼將數據存儲在 dataframe 中,將數據存儲在 memory 中。 另一種方法是像使用 Python 的 Pandas 一樣分塊讀取 CSV 文件。

調用?read.csv時,我看到以下 output:

nrows : 要讀入的最大行數。負值和其他無效值將被忽略。

skip :開始讀取數據之前要跳過的數據文件的行數。

為什么不嘗試一次將 5000 行讀取到 dataframe 寫入 PostgreSQL 數據庫,然后為每個文件執行此操作。

例如,對每個文件執行以下操作:

number_of_lines = 5000                 # Number of lines to read at a time
row_skip = 0                           # number of lines to skip initially
keep_reading = TRUE                    # We will change this value to stop the while

while (keep_reading) {
    my_data <- read.csv(x, nrow = number_of_lines , skip = row_skip)
    dbWriteTable(con, "prices", my_data , append = TRUE, row.names = FALSE) # Write to the DB

    row_skip = 1 + row_skip + number_of_lines   # The "1 +" is there due to inclusivity avoiding duplicates

# Exit Statement: if the number of rows read is no more the size of the total lines to read per read.csv(...)
if(nrow(my_data) < number_of_lines){
   keep_reading = FALSE
    } # end-if    
} # end-while

通過這樣做,您將 csv 分解成更小的部分。 您可以使用number_of_lines變量來減少循環數量。 這可能看起來有點棘手,涉及到一個循環,但我相信它會起作用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM