funcool / clojure.jdbc

JDBC library for Clojure
http://funcool.github.io/clojure.jdbc/latest/
Apache License 2.0
105 stars 26 forks source link

Docs: clarify cursor behavior #44

Open tomconnors opened 5 years ago

tomconnors commented 5 years ago

Using clojure.jdbc w/ Hikari CP and Postgresql 11.

When attempting to create a cursor as described in the docs the process still ends up trying to load the whole result set into memory.

(def conn (jdbc/connection pool))
(def cursor (jdbc/fetch-lazy conn "SELECT \"uuid\", data_bytes FROM visitor_data;"))
(def cursor-seq (jdbc/cursor->lazyseq cursor)) ;; hangs here

If I explicitly set auto-commit and the fetch size I don't have that problem:

(def conn (jdbc/connection pool))
(def cursor (jdbc/fetch-lazy conn "SELECT \"uuid\", data_bytes FROM visitor_data;"))
(.setFetchSize (.-stmt cursor) 50)
(.setAutoCommit (.getConnection (.-stmt cursor)) false)
(def cursor-seq (jdbc/cursor->lazyseq cursor))

is this a documentation problem or is the library expected to modify those settings for us?

shilder commented 5 years ago

That's postgresql-specific, but yes, docs could be improved

https://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor

shilder commented 5 years ago

You can pass fetch-size as option to fetch-lazy and evaluate code inside transaction to avoid setAutoCommit so you code should look like this:

(jdbc/atomic conn
  (with-open [cursor (jdbc/fetch-lazy conn "SELECT \"uuid\", data_bytes FROM visitor_data" {:fetch-size 50})]
    (doseq [row (jdbc/cursor->lazyseq cursor)]
      ;; Do something with each row
      )))

atomic will open transaction (setting autoCommit to false) and fetch-size will be passed to prepared statement by fetch-lazy (that should be mentioned in docs). You also need to close cursor after processing data.

tomconnors commented 5 years ago

Ah, I wasn't aware that :fetch-size was an option for fetch-lazy. That'll solve the problem for me. Might I suggest a couple documentation changes (that I'd be happy to make)?

shilder commented 5 years ago

I think any documentation improvements would be nice and useful