Ok, after a whole day with this, I need some help. I am trying to bulk insert some values using next-jdb
but I keep bumping into this error:
And here is my code:
(defn insert-multiple-design-versions!
"Given an array of versions containing the
:picture key as an array of uri's, extracts the
pictures from every design-version constructs the
insertable objects for versions and pictures and inserts them in the correct tables"
[db versions]
(let [db-pictures (into [] (flatten (map construct-db-pictures versions)))
db-versions (into [] (map #(dissoc % :pictures) versions))]
(jdbc/with-transaction
[tx db]
(sql/insert-multi! tx :design-version
[:design-id :version-id :name :description] db-versions)
(sql/insert-multi! tx :picture
[:uri :version-id :picture-id]
db-pictures))))
The error throws at the first insert-multi
, I assume it has something to do with sql types and I read the docs on next-jdbc/as-type
part but I donโt know how to use it. An example data from db-versions
is
{:description "Design option description"
:name "Design option 2"
:design-id "9cd035eb-a4d0-4ce2-ae75-b3b3cdcb76ed"
:version-id "4e901694-4279-4722-bfea-8fd841f772aa"}
And they are all stringsAlso, I am a beginner with clojure so any feedback on my code is greatly apreciated ๐
What are you passing in as versions
?
The error suggests you are passing MapEntry
values so I suspect you are passing a hash map where a sequence of hash maps is expected @ovidiu.stoica1094
hmmm
So you mean I am passing a map instead of an array
That does make sense. Let me debug a bit with this in mind
insert-multi!
expects a connection, a table, a list of column names and list of row values -- a list of lists (or a vector of vectors). (into [] (flatten ..))
is going to produce a single long sequence instead of a sequence of sequences so that's def. going to fail for the second insert (of db-pictures
).
It looks like versions
is a sequence of hash maps so db-versions
will also be a sequence of hash maps, so that is also not acceptable to insert-multi!
Omg ๐คฆ
Yes I was passing a list of maps with key-value pairs instead of a list of lists with only the values
juxt
would be very helpful here: (juxt :design-id :version-id :name :description)
produces a function that, when applied to a hash map, will pull out those values in the specified order (hash maps are inherently unordered).
So I think you want (map (juxt :the :keys :you :want) list-of-hash-maps)
I was actually looking for something exactly like that earlier ๐ฎ
flatten
is almost never the right answer to any problem ๐
๐
Iโll make sure to remember ๐
Thank you so much, @seancorfield and also, since I have a chance to talk to you, thank you so much for next.jdbc
. It has been a great help for me and Iโm definitely learning a lot from how you wrote the code in the lib. Iโm browsing through it from time to time
I'd probably do something like this:
(let [pic-cols [:design-id :version-id :name :description]
(sql/insert-multi! ds :design-version pic-cols (map (apply juxt pic-cols) pictures)))
(off the top of my head)
That is great. Easy to understand