Hi there, how can I format an insert-into when the values have nested maps or vectors that would be stored as jsonb?
(let [data [{:jsonb-column {:a 1 :b 2}
:jsonb-vector [1 2]
:text "text"}]]
(honeysql2/format {:insert-into :table
:values data}))In contrast if I use next.jdbc directly it works, but my use case requires special handling of on-conflict so I cant go that way.
(next.jdbc.sql/insert! tx :table {:jsonb-column {:a 1 :b 2}
:jsonb-vector [1 2]
:text "text"}):lift should work, assuming that whatever prepares the query knows how to convert from maps and vectors to SQL values:
(let [data [{:jsonb-column [:lift {:a 1 :b 2}]
:jsonb-vector [:lift [1 2]]
:text "text"}]]
(sql/format {:insert-into :table
:values data}))
=> ["INSERT INTO table (jsonb_column, jsonb_vector, text) VALUES (?, ?, ?)" {:a 1, :b 2} [1 2] "text"]Of course, it's that easy. Well, I'm never getting these two hours back. Thank you so much 🙏
I usually recommend asking others when you're stuck for 15-30 minutes. :)
Lesson learned
The next version of HoneySQL will give a better error message for this case, and the documentation will have several more mentions of :lift to guide people to using it.
Is it possible to edit a :select statement? i want to do a "select-keys" on a select to only use certain ones by their column or alias name instead of having to retype the subset
Well, it's "just data" so yeah...
(update dsl :select #(filterv #{:columns :to :keep} %)) or something like that?
Bear in mind that :select can also take arbitrary expressions so it would need to be smarter than that in general.
yeah, the arbitrary expression part is what i'm struggling with lol. i was hoping someone had already figured that out for me but that's okay, i can hack something together
And also you can have symbols or keywords -- so it's going to depend on your hygiene in building the selection.
(defn col-or-alias [select-item] (if (keyword? select-item) select-item (second select-item))) -- that should get you the column or alias name in most cases...
(update dsl :select #(filterv (comp #{:columns :to :keep} col-or-alias) %)) -- you still have to specify the set of columns/aliases you want to keep.
ah thanks, that looks close enough for my use case