[英]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.