Fork me on GitHub
#sql
<
2019-10-08
>
murtaza5218:10:38

If I want to run a sql query using next.jdbc/plan, and just realize the full result, how do I do that ? shouldnt (into [] results) realize it ?

seancorfield18:10:07

@murtaza52 You need to map something that realizes each row.

seancorfield18:10:25

You could just use execute! if you want the default array of realized hash map rows.

seancorfield18:10:54

But (into [] (map rs/datafiable-row) (jdbc/plan ,,,)) is roughly the same.

murtaza5218:10:36

I tried (into [] (map identity) results) to realize the rows, but that doesnt work too.

seancorfield18:10:52

No, because identity doesn't do anything to its argument.

murtaza5218:10:07

(into [] (map next.jdbc.result-set/datafiable-row) results) this gave an error too

murtaza5218:10:34

Wrong number of args (1) passed to:
   next.jdbc.result-set/eval6983/fn--6984/G--6974--6993

murtaza5218:10:55

I am using plan in the above

seancorfield18:10:03

Ah, yeah, my bad. I was doing that off the top of my head. datafiable-row needs arguments.

seancorfield18:10:26

Seriously tho', if you are just trying to get a fully realized result set, use execute! instead of plan.

seancorfield18:10:54

plan is for when you want to process a result set without realizing each row as a Clojure data structure.

seancorfield18:10:11

execute! is for obtaining a fully realized result set as Clojure data.

seancorfield18:10:08

(jdbc/execute! ds sql-vec opts) == (into [] (map #(rs/datafiable-row % ds opts)) (jdbc/plan ds sql-vec opts)) -- that's the full equivalence.

seancorfield18:10:09

(in order to datafy a row, datafiable-row needs the connectable and options so that it can perform SQL queries on your behalf if you navigate through the result)

seancorfield18:10:41

And when I say "full equivalence" I mean functionally the same -- under the hood they are implemented differently for performance reasons, so use the right tool (function) for the job 🙂

murtaza5219:10:27

@seancorfield thanks. I am trying to run initialization commands - CREATE DATABASE foo;, I dont need datafy/nav functionality, and I do want something that is eager and I dont have to realize. So I guess I will have to just run plan and then realize the result (so that it actually gets executed)?

seancorfield19:10:40

If you read the docs, for DDL operations, it recommends using execute-one!

seancorfield19:10:58

Since they will only ever return one "row" of information: an update count.

seancorfield19:10:07

The Getting Started page of the docs shows this in the example REPL session.

seancorfield19:10:57

DDL doesn't produce a result set so there's no point in trying to use plan with it -- you're only ever going to get back update counts.

murtaza5219:10:32

yup true, thanks for pointing out .... in plan does the query gets executed only when the result is reduced ?

seancorfield19:10:21

Yes, that's why plan has no ! -- on its own, it doesn't actually "do" anything. Only when it is reduced somehow does it actually run the SQL and process the result set.

murtaza5219:10:40

also is there an easy way to realize the result of plan for debugging, console printing etc ..

seancorfield19:10:35

@murtaza52 when working with plan, you will always have some sort of reduction process -- so that is what you would debug. plan doesn't have a "result" until you reduce it.

seancorfield19:10:37

In particular, if you (map str) over the rows, you will get the string representation of each row as a (realized) hash map.

seancorfield19:10:38

So inside your reduction process, just printlning (str row) should realize the row as a Clojure hash map and then turn it into a string and then print it.

murtaza5219:10:37

so (into [] (map str) results) should work

seancorfield19:10:26

That will give you a vector of strings (if that's what you want for debugging).

seancorfield19:10:35

I was thinking more of something like this:

seancorfield19:10:22

(into []
        (map #(do (println (str %)) (:id %)))
        (jdbc/plan ds ["select * from user where field = ?" some-value]))
So that prints each row but still also returns a vector of IDs

seancorfield19:10:38

The non-debugging form would just have (map :id)

seancorfield19:10:10

You can also just use (run! println (jdbc/plan ,,,)) -- but, generally, for debugging this stuff, I'd recommend instrumenting the reducing process itself instead.