Ok, ik weet niet zeker waarom dbWriteTable()
zou falen; er kan een soort mismatch zijn tussen versie/protocol. Misschien kunt u proberen de nieuwste versies van R, het RPostgreSQL-pakket, te installeren en, indien mogelijk, de PostgreSQL-server op uw systeem te upgraden.
Betreffende de insert into
tijdelijke oplossing mislukt voor grote gegevens, wat vaak wordt gedaan in de IT-wereld wanneer grote hoeveelheden gegevens moeten worden verplaatst en een eenmalige overdracht onhaalbaar/onpraktisch/schilferig is wat soms wordt aangeduid als batching of batchverwerking
. Kortom, je verdeelt de gegevens in kleinere stukjes en verzendt elk blok één voor één.
Een willekeurig voorbeeld:een paar jaar geleden schreef ik Java-code om werknemersinformatie op te vragen van een HR LDAP-server die beperkt was tot het leveren van slechts 1000 records tegelijk. Dus eigenlijk moest ik een lus schrijven om hetzelfde verzoek te blijven verzenden (met de vraagstatus bijgehouden met behulp van een of ander vreemd op cookies gebaseerd mechanisme ) en het verzamelen van de records in een lokale database totdat de server rapporteerde dat de query voltooid was.
Hier is wat code die de SQL handmatig construeert om een lege tabel te maken op basis van een gegeven data.frame, en vervolgens de inhoud van de data.frame in de tabel in te voegen met behulp van een geparametreerde batchgrootte. Het is meestal opgebouwd rond aanroepen om paste()
om de SQL-strings te bouwen, en dbSendQuery()
om de daadwerkelijke vragen te verzenden. Ik gebruik ook postgresqlDataType()
voor het maken van de tafel.
## 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
Merk op dat ik niet de moeite nam om een row.names
voor te zetten kolom naar de databasetabel, in tegenstelling tot dbWriteTable()
, die altijd zo'n kolom lijkt te bevatten (en geen enkele manier lijkt te bieden om dit te voorkomen).