honeysql

Discussion of https://github.com/seancorfield/honeysql :slightly_smiling_face:
abdullahibra 2020-01-04T15:57:36.001400Z

hello everyone

abdullahibra 2020-01-04T15:57:52.001800Z

what is the best way to handle sql errors?

abdullahibra 2020-01-04T15:58:33.002600Z

for example: if i have some columns with UNIQUE constraints and try to ingest that twice so i got error from sql, how can i reflect that into my code ?

abdullahibra 2020-01-04T15:58:56.003100Z

without write a clojure code to check if the record is already there before i ingest it into the db

dharrigan 2020-01-04T17:19:37.003400Z

Which DB is it?

abdullahibra 2020-01-04T18:47:27.003700Z

@dharrigan posgtresql

seancorfield 2020-01-04T18:53:53.004400Z

(try (sql operation) (catch SomeException e (recover-from-it "etc")))

abdullahibra 2020-01-04T19:04:42.005200Z

i'm trying to get the duplicate error from sql, i'm using honeysql i got: Exception in execute!, is there a way to get that exception ?

seancorfield 2020-01-04T19:08:02.005700Z

I don't understand what you're asking. try/`catch` is how you catch exceptions.

seancorfield 2020-01-04T19:08:55.006500Z

Perhaps if you share the code you're trying to use and provide a bit more detail about the exception and explain why it isn't what you want...?

seancorfield 2020-01-04T19:09:27.006700Z

For example:

(try
        (jdbc/insert! db-spec :user_activity all-activity)
        (catch SQLIntegrityConstraintViolationException _))

seancorfield 2020-01-04T19:09:45.007Z

where we already imported that:

(:import (java.sql SQLIntegrityConstraintViolationException))

seancorfield 2020-01-04T19:10:27.007200Z

^ @abdullahibra

dharrigan 2020-01-04T20:32:43.007400Z

I do something different

dharrigan 2020-01-04T20:32:47.007600Z

basically I ignore

dharrigan 2020-01-04T20:33:09.007800Z

i.e.,g on conflict do nothing

dharrigan 2020-01-04T20:33:21.008100Z

since it already exists in the db

seancorfield 2020-01-04T20:43:16.008500Z

@dharrigan That sort of thing is DB-specific tho'...

dharrigan 2020-01-04T20:43:30.008800Z

yes, but he's mentioned he uses postgres

dharrigan 2020-01-04T20:43:38.009100Z

so might as well use the feature of postgres

dharrigan 2020-01-04T20:43:42.009300Z

mysql has a similar feature

dharrigan 2020-01-04T20:43:47.009500Z

why not use it? 🙂

dharrigan 2020-01-04T20:44:07.009800Z

keep things generic, where appropriate, but specific when needed

seancorfield 2020-01-04T20:45:20.010700Z

Fair point. I was trying to answer the exception-based stuff in his question, and since I don't use PG, I didn't think about SQL-level stuff.

seancorfield 2020-01-04T20:46:17.011300Z

(and I'm not sure that PG-specific SQL would fit into HoneySQL's DSL off the top of my head)

dharrigan 2020-01-04T20:46:37.011500Z

true, I use this:

dharrigan 2020-01-04T20:46:51.011700Z

(defmethod fmt/format-clause :on-conflict-do-nothing [[_ _] _]
  (str "ON CONFLICT DO NOTHING"))

(defhelper on-conflict-do-nothing [m _]
  (assoc m :on-conflict-do-nothing []))

dharrigan 2020-01-04T20:47:44.012700Z

I think also, there is more power in the on conflict, i.e., you can tell postgresql to do something else if that condition is raised

dharrigan 2020-01-04T20:48:00.013100Z

and it happens on the db, doesn't involve a round-trip back to the server

dharrigan 2020-01-04T20:48:23.013600Z

but yes, your point is valid too - if he chooses to go the exception route, totally fine in my books as well

seancorfield 2020-01-04T20:56:13.014400Z

Looks like MySQL has ON DUPLICATE KEY UPDATE x=x (where x is arbitrarily one of the columns, as I understand what I'm seeing on SO).

seancorfield 2020-01-04T21:02:40.014900Z

ANSI has a MERGE statement (but not all databases support that -- "of course").

dharrigan 2020-01-04T21:03:32.015100Z

🙂

dharrigan 2020-01-04T21:04:15.015500Z

xkcd 927 comes to mind

seancorfield 2020-01-04T21:05:29.016300Z

As someone who spent eight years on the ANSI C++ Standards Committee I can only say "preach" as far as that cartoon is concerned 🙂