Oke, saya tidak yakin mengapa dbWriteTable()
akan gagal; mungkin ada semacam ketidakcocokan versi/protokol. Mungkin Anda dapat mencoba menginstal versi terbaru R, paket RPostgreSQL, dan memutakhirkan server PostgreSQL di sistem Anda, jika memungkinkan.
Mengenai insert into
solusi gagal untuk data besar, apa yang sering dilakukan di dunia TI ketika sejumlah besar data harus dipindahkan dan transfer satu kali tidak dapat dilakukan/tidak praktis/terkelupas adalah apa yang kadang-kadang disebut sebagai batching atau pemrosesan batch
. Pada dasarnya, Anda membagi data menjadi potongan yang lebih kecil dan mengirimkan setiap potongan satu per satu.
Sebagai contoh acak, beberapa tahun yang lalu saya menulis beberapa kode Java untuk menanyakan informasi karyawan dari server HR LDAP yang dibatasi hanya menyediakan 1000 catatan pada satu waktu. Jadi pada dasarnya saya harus menulis loop untuk terus mengirim permintaan yang sama (dengan status kueri dilacak menggunakan semacam mekanisme aneh berbasis cookie ) dan mengumpulkan catatan ke dalam database lokal hingga server melaporkan kueri selesai.
Berikut ini beberapa kode yang secara manual menyusun SQL untuk membuat tabel kosong berdasarkan data.frame yang diberikan, lalu menyisipkan konten data.frame ke dalam tabel menggunakan ukuran batch yang diparameterisasi. Ini sebagian besar dibangun di sekitar panggilan ke paste()
untuk membangun string SQL, dan dbSendQuery()
untuk mengirim pertanyaan yang sebenarnya. Saya juga menggunakan postgresqlDataType()
untuk pembuatan tabel.
## connect to the DB
library('RPostgreSQL'); ## loads DBI automatically
drv <- dbDriver('PostgreSQL');
con <- dbConnect(drv,host=...,port=...,dbname=...,user=...,password=...);
## define helper functions
createEmptyTable <- function(con,tn,df) {
sql <- paste0("create table \"",tn,"\" (",paste0(collapse=',','"',names(df),'" ',sapply(df[0,],postgresqlDataType)),");");
dbSendQuery(con,sql);
invisible();
};
insertBatch <- function(con,tn,df,size=100L) {
if (nrow(df)==0L) return(invisible());
cnt <- (nrow(df)-1L)%/%size+1L;
for (i in seq(0L,len=cnt)) {
sql <- paste0("insert into \"",tn,"\" values (",do.call(paste,c(sep=',',collapse='),(',lapply(df[seq(i*size+1L,min(nrow(df),(i+1L)*size)),],shQuote))),");");
dbSendQuery(con,sql);
};
invisible();
};
## generate test data
NC <- 1e2L; NR <- 1e3L; df <- as.data.frame(replicate(NC,runif(NR)));
## run it
tn <- 't1';
dbRemoveTable(con,tn);
createEmptyTable(con,tn,df);
insertBatch(con,tn,df);
res <- dbReadTable(con,tn);
all.equal(df,res);
## [1] TRUE
Perhatikan bahwa saya tidak repot-repot menambahkan row.names
kolom ke tabel database, tidak seperti dbWriteTable()
, yang sepertinya selalu menyertakan kolom seperti itu (dan sepertinya tidak menyediakan cara apa pun untuk mencegahnya).