我想要一個函數從select語句寫入數據庫sql轉儲到文本文件。返回的數量可能非常大,我有興趣儘快完成此操作。數據庫轉儲到「行完成」的副作用文本文件
對於大的結果集,我還需要記錄每個x-interval自從上一次x-interval以來寫入的總行數和每秒寫入的行數。我有一個(地圖),實際上是在一個(with-open)期間進行寫操作,所以我相信記錄行的副作用應該在那裏發生。 (見代碼註釋)。
我的問題是:
- 我怎樣寫的時間間隔內「行每秒」和「總行到目前爲止」?
- 在將大型jdbc結果集寫入文件(或命名管道,批量加載程序等)時,是否還有其他要記住的內容?
- (地圖)函數週圍的(doall)是否獲取所有結果...使其非懶惰並且可能需要內存密集型?
固定寬度可以作爲選項嗎?我相信對於命名管道來說散裝加載器會更快。權衡將在磁盤I/O上代替CPU利用率進行下游解析。然而,這可能需要對返回的結果集內省(與.getMetaData?)
(ns metadata.db.table-dump [:use [clojure.pprint] [metadata.db.connections] [metadata.db.metadata] [clojure.string :only (join)] [taoensso.timbre :only (debug info warn error set-config!)] ] [:require [clojure.java.io :as io ] [clojure.java.jdbc :as j ] [clojure.java.jdbc.sql :as sql] ] ) (set-config! [:appenders :spit :enabled?] true) (set-config! [:shared-appender-config :spit-filename] "log.log") (let [ field-delim "\t" row-delim "\n" report-seconds 10 sql "select * from comcast_lineup " joiner (fn [v] (str (join field-delim v) row-delim)) results (rest (j/query local-postgres [sql ] :as-arrays? true :row-fn joiner)) ] (with-open [wrtr (io/writer "test.txt")] (doall (map #(.write wrtr %) ; Somehow in here i want to log with (info) rows written so ; far, and "rows per second" every 10 seconds. results)) ) (info "Completed write"))
好東西,謝謝。公認。 – joefromct