Clojure.java.jdbc lazy request

I have a query that is basically equal select *. In development, this table is only 30,000 rows, but in production it will be much larger. So I want to use this query lazily. Why is the request below not lazy? I am using Postgres 9.5.4.1.

(do
  (def pg-uri {:connection-uri "jdbc:postgresql://localhost/..."})
  (def row (atom 0))
  (take 10 (clojure.java.jdbc/query 
          pg-uri
          ["select * from mytable"]
          {:fetch-size 10
           :auto-commit false
           :row-fn (fn [r] (swap! row inc))}))
  @row) ;;=> 300000
+3
source share
2 answers

First, see https://jdbc.postgresql.org/documentation/83/query.html#query-with-cursor .

Decided so.

(jdbc/with-db-transaction [tx connection]
  (jdbc/query tx
    [(jdbc/prepare-statement (:connection tx)
                              "select * from mytable"
                              {:fetch-size 10})]
     {:result-set-fn (fn [result-set] ...)}))

where :result-set-fnis a function that consumes a lazy set of results.

with-db-transaction autoCommit false. :fetch-size query, prepare-statement .

+4

. :result-set-fn . , :row-fn.

. Clojure . , .

jdbc/query , , . : result-set-fn , set ( ), . doall:

(defn hi-lo [rs] [(first rs) (last rs)])

;; Find the highest- and lowest-cost fruits
(jdbc/query db-spec
            ["select * from fruit order by cost desc"]
            :result-set-fn hi-lo)
;; -> [{:grade nil, :unit nil, :cost 77, :appearance nil, :name "Kumquat"}
;;     {:grade 1.4, :unit nil, :cost 10, :appearance "rotten", :name "Tomato"}]

: row-fn , . :

(defn add-tax [row] (assoc row :tax (* 0.08 (row :cost))))

(jdbc/query db-spec
             ["select name,cost from fruit where cost = 12"]
             :row-fn add-tax)
;; -> ({:tax 0.96, :cost 12, :name "Plum"} {:tax 0.96, :cost 12, :name "Fig"})
+1

Source: https://habr.com/ru/post/1657621/


All Articles