postgresql - clojure.java.jdbc requête paresseuse




(2)

J'ai une requête qui est essentiellement un select * . En développement, cette table n'est que de 30000 lignes, mais en production, elle sera beaucoup plus grande. Donc, je veux consommer cette requête paresseusement. Pourquoi la requête ci-dessous n'est-elle pas paresseuse? J'utilise 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

Premièrement, voir https://jdbc.postgresql.org/documentation/83/query.html#query-with-cursor .

Je l'ai résolu comme ça.

(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] ...)}))

:result-set-fn est une fonction qui consomme le jeu de résultats paresseux.

with-db-transaction prend en charge l' autoCommit définie sur false . :fetch-size n'est pas transmis depuis la query , vous devez donc vous prepare-statement même prepare-statement une prepare-statement .


Vous n'avez pas besoin de la transaction et des instructions préparées ci-dessus. C'est l'utilisation de :result-set-fn qui provoque la consommation de la paresseuse. Vous avez peut-être voulu utiliser :row-fn place.

Pour plus de détails s'il vous plaît voir le livre de cuisine Clojure. Une version imprimée est également disponible, que je recommande.

La fonction jdbc / query possède plusieurs paramètres de mots-clés facultatifs qui contrôlent la façon dont elle construit l'ensemble de résultats renvoyé. Le paramètre: result-set-fn spécifie une fonction qui est appliquée à l'ensemble de résultats complet (une séquence paresseuse) avant qu'elle ne soit retournée. L'argument par défaut est la fonction 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"}]

Le paramètre: row-fn spécifie une fonction qui est appliquée à chaque ligne de résultat à mesure que le résultat est construit. L'argument par défaut est la fonction d'identité:

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




clojure