Comments (5)
I've had some really weird problems with PGobjects caching something when I use tools.namespace.repl to reload code. My colleagues think this is due to a bug deep in the Postgres JDBC driver 🤷♂ . As a workaround, I CAST
the JSON string to JSONB:
(require '[honeysql.core :as sql])
(defn ->jsonb [data]
(sql/call :cast (json/generate-string data) :jsonb))
(m/add-type! :jsonb
:in ->jsonb
:out #(json/parse-string % keyword))
FWIW, I use m/types
like the docs say and like you show in the opening message, and I haven't had any problems.
from toucan.
Answering my own question, it seems that the problem is in the (m/types)
function that isn't working. Instead, you should use (m/merge)
. Here's a working implementation in case anyone finds it useful:
(defn- clj->pgobject
[value]
(doto (PGobject.)
(.setType "json")
(.setValue (json/generate-string value))))
(m/add-type! :json
:in clj->pgobject
:out #(json/parse-string (.getValue %) keyword))
(m/defmodel Integration :integrations)
(extend (class Integration)
m/IModel
(merge m/IModelDefaults
{:types (constantly {:data :json})}))
from toucan.
Thanks for posting your solution @rlander.
I think in the future I want to move to a more idiomatically-Clojure way of doing things, using multimethods instead of the current protocols + non-Clojurey merge m/IModelDefaults
, e.g. something like
(m/defmodel Integration :integrations)
;; Integration.data should be treated as JSON
(m/defmethod m/types [Integration :data] [_ _]
:json)
This would have the benefit of letting you for example define a type for all columns with the same name, e.g.
;; All `data` columns should be treated as JSON
(m/defmethod m/types [Object :data] [_ _]
:json)
And ideally allowing you to put the models in a hierarchy of some sort so you could do something like
(m/defmodel ModelWithJSONData :abstract? true)
(m/derive Integration ModelWithJSONData)
;; all models that derive from ModelWithJSONData should have their :data column treated as JSON
(m/defmethod m/types [ModelWithJSONData :data] [_ _]
:json)
Doing this in a way that is minimally disruptive to existing projects is my biggest concern so I'm letting these ideas marinate for a while
from toucan.
Thanks for the response! I agree that multi-methods would be easier to easier (and more idiomatic) to extend than the current way, though I'm not sure I like the hierarchy part. I don't see a way around releasing a breaking version though. Anyways, I'd be up to contribute if you don't mind. Should I open a new issue and close this one?
from toucan.
is it possible to search by jsonb field?
from toucan.
Related Issues (20)
- Setting :identifiers for JDBC connection is broken with toucan.db/query in 1.13.0 HOT 2
- Update! with empty map should be no-op
- Need tests for a model with byte array PK
- apply-type-fns should give better error message if type does not exist HOT 1
- Rollbacks in db/transaction
- apply-type-fns does not apply the function if the value is false HOT 3
- Toucan put a string as table name in sql using mysql HOT 2
- Params in query call possible ? HOT 1
- Fix docs to clarify that `update-where!` doesn't call pre-update (or post-update)
- No implementation of method: :post-insert of protocol: #'toucan.models/IModel found for class: nil HOT 2
- Does Toucan support enumerated types? HOT 2
- Will not use Transaction when call db/insert with a binding to *db-connection*
- Model instance to map HOT 1
- Hydrate many to many relation with intermediate table.
- [Question] Ignore case on select
- Select queries do not work with custom types HOT 1
- Any Plans or Interest in Moving to HoneySQL 2? HOT 5
- Select query does not work with sub-query
- Migrations? HOT 4
- Add ns qualified keyword options to IModel HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from toucan.