sql

All things SQL and JDBC...
Ovidiu Stoica 2021-02-15T17:56:10.073300Z

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:

Ovidiu Stoica 2021-02-15T17:56:27.073800Z

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))))

Ovidiu Stoica 2021-02-15T17:58:31.075500Z

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 strings

Ovidiu Stoica 2021-02-15T17:59:50.076300Z

Also, I am a beginner with clojure so any feedback on my code is greatly apreciated ๐Ÿ˜„

seancorfield 2021-02-15T18:00:24.077Z

What are you passing in as versions?

seancorfield 2021-02-15T18:01:39.078200Z

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

Ovidiu Stoica 2021-02-15T18:02:06.078400Z

hmmm

Ovidiu Stoica 2021-02-15T18:02:16.078700Z

So you mean I am passing a map instead of an array

Ovidiu Stoica 2021-02-15T18:04:35.079800Z

That does make sense. Let me debug a bit with this in mind

seancorfield 2021-02-15T18:06:43.081900Z

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).

seancorfield 2021-02-15T18:07:35.082800Z

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!

Ovidiu Stoica 2021-02-15T18:07:45.083Z

Omg ๐Ÿคฆ

Ovidiu Stoica 2021-02-15T18:08:21.083800Z

Yes I was passing a list of maps with key-value pairs instead of a list of lists with only the values

seancorfield 2021-02-15T18:09:31.086100Z

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).

seancorfield 2021-02-15T18:10:06.086900Z

So I think you want (map (juxt :the :keys :you :want) list-of-hash-maps)

Ovidiu Stoica 2021-02-15T18:10:14.087100Z

I was actually looking for something exactly like that earlier ๐Ÿ˜ฎ

seancorfield 2021-02-15T18:10:27.087600Z

flatten is almost never the right answer to any problem ๐Ÿ™‚

Ovidiu Stoica 2021-02-15T18:10:33.087800Z

๐Ÿ™‚

Ovidiu Stoica 2021-02-15T18:10:43.088200Z

Iโ€™ll make sure to remember ๐Ÿ˜„

Ovidiu Stoica 2021-02-15T18:11:43.089700Z

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

seancorfield 2021-02-15T18:12:02.090100Z

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)))

seancorfield 2021-02-15T18:12:11.090300Z

(off the top of my head)

Ovidiu Stoica 2021-02-15T18:12:57.090900Z

That is great. Easy to understand