2016-03-17 9 views
6

Sto cercando di inserire i record in Postgres DB, e la sua assunzione di circa 3 ore, mentre ci vogliono 40 secondi utilizzando python psycopg2 e il metodo cursor.copy_fromrecord dei file Inserire le Postgres DB utilizzando clojure JDBC sta prendendo molto tempo rispetto ai psycopg2 pitone

Cosa c'è di sbagliato nel mio codice, utilizzando anche clojure.java.jdbc/db-do-preparato richiede anche circa 3 ore. Per favore aiuto!

dimensione del file è 175M e ha 409,854 record

(defn- 
    str<->int [str] 
    (let [n (read-string str)] 
    (if (integer? n) n))) 

(with-open [file (reader "/path/to/foo.txt")] 
    (try 
     (doseq [v (clojure-csv.core/parse-csv file)] 

     (clojure.java.jdbc/insert! db :records 
         nil 
         [(v 0) (v 1) (v 2) (str<->int (v 3))])) 
     (println "Records inserted successfully") 
     (Exception e 
     (println (.getNextException e) e)))) 

risposta

3

E 'probabilmente a causa di non utilizzare dosaggio nella versione Clojure. Si inseriscono le righe una alla volta ciascuna attivando il commit.

Se si desidera farlo in Clojure di quanto necessario alle file partition da file CSV e insert! ogni blocco come un commit in batch. È necessario utilizzare l'ultima versione di Arity che accetta più col-val-vec s. Il codice di esempio (non controllato, solo per mostrare l'idea):

(defn row->col-spec [row] 
    [(v 0) (v 1) (v 2) (str<->int (v 3))]) 

(with-open [csv-file (reader "/path/to/foo.txt")] 
    (try 
    (->> csv-file 
     (clojure-csv.core/parse-csv) 
     (map row->col-spec) 
     (partition 50) 
     (map (fn [batch] clojure.java.jdbc/insert! db :records ["col1" "col2" "col3" "col4"] batch)) 
     (dorun)) 
    (catch Exception e 
     (println e)))) 

Se non si hanno a che fare in Clojure quindi utilizzando il comando psql's COPY sembra essere l'opzione più semplice e veloce:

COPY records FROM '/path/to/foo.txt' WITH (FORMAT csv, DELIMITER ',', NULL 'NULL'); 
+1

Sto usando Clojure versione 1.8.0, puoi condividere un esempio di come può essere fatto in clojure –

+0

Ho aggiunto un esempio di codice in Clojure - testarlo come non l'ho eseguito. –

+0

Bene, ho usato il comando Copia PSQL che hai suggerito, non avevo nemmeno bisogno di trasmettere ogni campo, questo è davvero più facile e veloce. Grazie –

Problemi correlati