sql

All things SQL and JDBC...
2020-03-28T05:30:55.044100Z

Hi, I am trying to update a table in a postgres db with next-jdbc using the update! fn as follows:

(defn ->table [s]
  (let [_ (debug (str "->table:" s))]
  (str/replace s #"-" "_")))

(defn ->col [s]
  (let [_ (debug (str "->col:" s))]
    (str/replace
     (str/replace s #"-" "")
     #"\."
     "_")))

(defn update-tasks [db tasks]
  (let [ds (jdbc/get-datasource db)
        results (f/try*
                 (doseq
                     [t tasks]
                   (sql/update! ds :my-tasks t  {:table-fn ->table
                                                 :column-fn ->col})))]
    (if (f/failed? results)
      results
      tasks)))
but get this exception:
Can't infer the SQL type to use for an instance of api.resources.db$__GT_table. Use setObject() with an explicit Types value to specify the type to use.
org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of vms_api.resources.db$__GT_table. Use setObject() with an explicit Types value to specify the type to use.
 at org.postgresql.jdbc.PgPreparedStatement.setObject (PgPreparedStatement.java:978)
I'm not sure, how the :table-fn is getting down into the postgres jdbc driver as a value. I am using this successfully with an insert! fn that looks almost identical. Am I doing something wrong here?

seancorfield 2020-03-28T05:47:57.045100Z

@pdmct You have the wrong arguments to update!

seancorfield 2020-03-28T05:49:08.046200Z

It takes a connectable (`ds`), a table (`:my-tasks`), a map of updates (`t`), a where map or clause -- which is missing -- and then then options.

2020-03-28T05:49:44.046500Z

ok, I see

2020-03-28T05:49:56.046700Z

thanks

seancorfield 2020-03-28T05:50:19.047100Z

update! takes one more argument than insert! 🙂

seancorfield 2020-03-28T05:50:59.047600Z

(I must admit, I was confused by that error message at first!)

2020-03-28T05:52:27.048600Z

yes, that isn't obvious , I have been scratching my head for while on this. so some more like this:

(sql/update! ds :analytics-tasks t {:id (:id t)}
                                {:table-fn ->table
                                 :column-fn ->col}))

2020-03-28T05:54:00.048900Z

that's much better

seancorfield 2020-03-28T05:54:19.049400Z

Yup, that will perform the update WHERE id = ? ... (:id t)

2020-03-28T05:54:34.049900Z

cool, thanks

seancorfield 2020-03-28T05:55:09.050600Z

The problem is that it couldn't tell the difference between the map {:id (:id t)} and the map {:table-fn ->table :column-fn ->col} since both are maps and options are ... optional.

seancorfield 2020-03-28T05:55:26.051200Z

So even next.jdbc.specs couldn't have helped you here.

2020-03-28T05:58:30.054400Z

yes, I see that now. thanks for the quick response

jaime 2020-03-28T06:40:20.054500Z

got it :thumbsup: