2016-03-17 29 views
6

piton psycopg2 kıyasla uzun sürüyorsa ve piton psycopg2 ve cursor.copy_from yöntemitakın dosya kayıtları Ben postgres veritabanına kayıt eklemek için çalışıyorum

kullanarak 40seconds alırken onun yaklaşık 3 saat süren

clojure.java.jdbc/db-do-ready kullanarak kodumda neyin yanlış olduğu da yaklaşık 3 saat sürüyor. Lütfen yardım edin!

Dosya boyutu 175M olduğunu ve muhtemelen sizin Clojure sürümünde istifleme kullanmayan nedeniyle olduğunu 409.854 kayıtları

(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)))) 

cevap

3

sahiptir. Her biri sırayı tetikleyen satırları tek tek eklersiniz.

Eğer Clojure içinde CSV dosyalarından partition satırdan ve bir toplu işlem olarak her yığın için insert!'dan daha fazla yapmak isterseniz. Birden çok col-val-vec s kabul eden son aritmetik sürümünü kullanmanız gerekir. Örnek kod (sadece fikir göstermek için, işaretli değil):

(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)))) 

sonra psql's COPY komutunu kullanarak Clojure bunu yapmak zorunda kolay ve en hızlı seçenek olarak görünmektedir yoksa:

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

Clojure sürüm 1.8.0 kullanıyorum, clojure –

+0

içinde nasıl yapılabileceğine dair bir örnek paylaşırsanız Clojure'da bir kod örneği ekledim - çalıştırmamışım gibi test et. –

+0

Eh, önerdiğin PSQL Copy komutunu kullandım, hatta her bir alana girmem gerekiyordu, bu gerçekten daha kolay ve daha hızlı. Teşekkürler –

İlgili konular