Fork me on GitHub
#datomic
<
2023-12-22
>
hifumi12304:12:08

How do people normally deal with adding/removing namespaces in keys? Say my database has attributes :thing/foo and :thing/bar. I am writing a function accepting a db and a map containing some keys. This map conforms to a spec like (s/keys :req-un [:thing/foo] :opt-un [:thing/bar]). In Datomic, the attributes are namespaced keys, but the map in the function does not have namespaced keys. So I cannot pass the map directly into d/transact. To alleviate this problem, do you write your specs so that the map keys must be qualified? Or do you manually construct the transaction data within the function? e.g.

(d/transact conn
            {:tx-data [(update-keys m 
                                    (fn [k]
                                      (keyword "thing" (name k))))]})
I don’t like this approach (due to time and effort spent in marshaling data). Another “bad approach” I have considered, but rejected, is
(let [{:keys [foo bar]} m]
  (d/transact conn {:tx-data [#:thing{:foo foo :bar bar}]}))
This will blow up whenever m does not have :thing/bar . So I am wondering if I am missing something obvious or there is a good practice I am simply unaware of.

caleb.macdonaldblack04:12:58

> or there is a good practice I am simply unaware of. namespace all your keys everywhere, not just in your database

hifumi12304:12:37

Ah, I forgot to mention one more thing in my post: whether people just rely on the caller of database-using functions to use namespaced keys

hifumi12304:12:53

I sort of implied it with “refactoring key specs” to use :req instead of :req-un

caleb.macdonaldblack04:12:21

We use namespaced keywords everywhere. all data passed through function (like maps) will have namespaced keywords. It’s less imported for non-domain-specific data however. https://clojure.org/about/spec#_names_are_important https://clojure.org/about/spec#_global_namespaced_names_are_more_important If you have to transform keywords from no-ns to ns (like if you’re consuming a 3rd party API or something), then I would do that early as possible in your application,

(let [m {:foo 1 :bar 2}]
  (update-keys m (comp (partial keyword "thing") name)))

👍 1
caleb.macdonaldblack05:12:05

It’s also not uncommon to qualify the keywords when decoding another data-format (like json)

(jsonista.core/read-value 
  "{\"foo\": \"bar\"}" 
  (jsonista.core/object-mapper 
    {:decode-key-fn (comp (partial keyword "thing") name)}))

hifumi12305:12:22

Thanks for the advice! Thankfully for this application I have full control over the stack (Clojure backend, ClojureScript frontend, Datomic as database), so I can use EDN and afford to have namespace-qualified keys everywhere.

neilprosser11:12:38

Does anyone know whether the NodeDbCount metric for Datomic Cloud listed on https://docs.datomic.com/cloud/operation/monitoring.html#metrics is new? We've got systems between <tel:995-9204|995-9204> and <tel:1067-9276|1067-9276> and I can't see it in CloudWatch.