seancorfield / honeysql

Turn Clojure data structures into SQL
https://cljdoc.org/d/com.github.seancorfield/honeysql/CURRENT
1.77k stars 174 forks source link

Formatting unhashable objects #509

Closed jcf closed 1 year ago

jcf commented 1 year ago

I have an unusual setup where I'm trying to transact numpy ndarrays returned by libpython-clj.

I've added a SettableParameter to next.jdbc to serialise these fancy lists so I can pass them to pgvector, but ran into a problem with HoneySQL where the inability to hash an ndarray broke format-values.

(ns example
  (:require
   [clojure.string :as str]
   [libpython-clj2.python :as py]
   [libpython-clj2.python.protocols]
   [libpython-clj2.require :refer [require-python]]
   [next.jdbc.prepare :as prepare])
  (:import
   (org.postgresql.util PGobject)))

(require-python
 '[numpy :as np])

(extend-protocol prepare/SettableParameter
  libpython_clj2.python.protocols.PPythonType
  (set-parameter [v
                  ^java.sql.PreparedStatement s
                  ^long i]
    (case (py/python-type v)
      :ndarray
      (.setObject s i (doto (PGobject.)
                        (.setType "vector")
                        (.setValue (str "[" (str/join "," (py/py. v tolist)) "]"))))

      ;; Default to setting the object as is.
      (.setObject s i v))))

https://clojurians.zulipchat.com/#narrow/stream/151924-data-science/topic/next.2Ejdbc.20and.20libpython-clj

jcf commented 1 year ago

Massive thank you to @joinr for helping work out the SettableParameter extension via PPythonType, too. 🙌