This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-20
Channels
- # aleph (11)
- # announcements (3)
- # babashka (35)
- # babashka-sci-dev (28)
- # beginners (29)
- # calva (51)
- # cider (33)
- # clj-kondo (26)
- # clj-on-windows (1)
- # clojure (40)
- # clojure-austin (1)
- # clojure-europe (47)
- # clojure-nl (9)
- # clojure-norway (7)
- # clojure-uk (5)
- # clojurescript (69)
- # conjure (30)
- # cursive (7)
- # data-science (9)
- # datomic (2)
- # etaoin (10)
- # events (2)
- # fulcro (1)
- # graalvm (1)
- # gratitude (6)
- # helix (16)
- # honeysql (20)
- # hyperfiddle (14)
- # inf-clojure (2)
- # jobs (1)
- # jobs-discuss (12)
- # kaocha (9)
- # leiningen (2)
- # lsp (4)
- # malli (8)
- # music (9)
- # off-topic (12)
- # pathom (10)
- # portal (14)
- # practicalli (15)
- # re-frame (27)
- # reitit (7)
- # remote-jobs (4)
- # sci (37)
- # shadow-cljs (16)
- # sql (8)
- # tools-deps (6)
- # vim (6)
- # xtdb (21)
Does honeysql support anything for generating a batch values insert statement as expected by jdbc-next? ie. rather than generating INSERT INTO table (id, col) VALUES (?, ?), (?, ?), (?, ?)
when doing (sql/format {:insert-into :table :values [{:id 1, :col "a"}, {:id 2, :col "b"}, {:id 3, :col "c"})
it does INSERT INTO table (id, col) VALUES (?, ?)
I assume you mean jdbc/execute-batch!
there? Feel free to open an issue and I'll give it some thought. The machinery that does that formatting is deep inside the formatter and it would affect a lot of how parameters are handled -- because anything could be an expression and have parameters lifted out of it.
An easier "win" would be to enhance https://cljdoc.org/d/com.github.seancorfield/next.jdbc/1.2.780/api/next.jdbc.sql#insert-multi! so it could accept a sequence of hash maps and validate/split them into cols and rows.
If I'm understanding the docs correctly insert-multi!
will still not use batch statements (which makes sense as default). I'm specifically trying to get to batch statements (because my JDBC driver warns me when I don't use them 😛)
@UEC8W94AE It's a tricky area, since both PG and MySQL need (different) JDBC URL parameters to perform the statement rewriting necessary to actually batch things properly...
...but changing insert-multi!
to conditionally use execute-batch!
would be "relatively straightforward" and would be my preference, rather than trying to conditionally change HoneySQL's :insert-into
behavior (since it is actually :values
that would be affected -- and there's an interaction with :columns
as well).
That all makes sense @U04V70XH6 - I'll look at extending insert-multi!
to support the hash maps + add an optional :batch
option that converts it to using execute-batch!
instead of execute!
- thanks for the help!
Thanks! That's definitely something I'd consider a PR for -- with multi-database tests and documentation, please -- or just create an issue as a placeholder and provide your thoughts.
Let me know if you want me to just close https://github.com/seancorfield/honeysql/issues/408 with some of your thoughts (in case somebody else goes looking on GH)
That code would fail if inserting composite values since it doesn't account for nested parens in the generated SQL.
(feel free to close it -- the actual changes needed are almost certainly much more complex than they might appear)
Closed! Thanks again for the input
Available to test via git deps or https://clojars.org/com.github.seancorfield/next.jdbc/versions/1.2.999-SNAPSHOT -- thank you!
Thanks for the quick publish!
Thanks for the high quality contribution!
Confirmed that it's working for me
If not, would you be open to a PR?
Something like:
(let [[sql & groups] (sql/format {:insert-into :table :values val-seq} {:batch true})]
(jdbc/insert-batch! connectable sql groups))
What I currently have (and works fine - but just wondering if this is something honeysql would like):
(defn- -format-batch-insert
"Convert a multi-parameterized sql insert map into a statement suitable for batch use.
Returns a sequence that can be destructured as `[sql & param-groups]`"
[{:keys [insert-into values]}]
(let [key-count (-> values first keys count)
[raw-sql & raw-params] (sql/format {:insert-into insert-into :values values})
sql (->> (str/split raw-sql ")")
(take 2)
(str/join ")")
(#(str % ")")))]
(concat
[sql]
(partition key-count raw-params))))
Obviously the impl could be cleaner inside of honeysql itself