I did not know that! Cool.
Yep you cannot do that on the same process. You can however make the choice independently per process. https://docs.datomic.com/on-prem/operation/valcache.html#vs-memcached
has there been any news on cloud disaster recovery, the discussions donโt seem active https://forum.datomic.com/t/cloud-backups-recovery/370/10 we currently have a hand rolled tx log backup/restore solution but itโs a bit painful to maintain
Maybe you're aware already but there's a feature request on ask.datomic: https://ask.datomic.com/index.php/431/cloud-backup-and-recovery
The recommendation for enums in Datomic is to https://docs.datomic.com/cloud/schema/schema-modeling.html#enums. Using :db/ident
as an enum value complicates the use with d/pull
. Everywhere you pull an entity, you'll need to write code to deal with the nested enum entity. For example, say I have a :user/type
enum that is defined as suggested by that doc (card one, ref attr). Anytime I pull my :user/type
attribute, I need to write code to unnest the :user/type
value.
(d/pull (d/db conn) '[:user/type] [:user/id "a"])
=> #:user{:type #:db{:id 87960930222153, :ident :user.type/a}}
How are folks dealing with this? Just always wrapping the d/pull return with something like (update :user/type :db/ident)
? Perhaps always remembering to specify the pull pattern for all enum attributes as (:user/type :xform my-ns/get-db-ident)
, where my-ns/get-db-ident
is just (def get-db-ident :db/ident)
?is walk so slow? Iโve used it heavily and never had it be a problem in my work loads
We had a specific usecase where we had very big resultsets (~150,000 entities + nesting). That's when we replaced the postwalk. Generally it's fine for sure.
that is a big result, out of curiosity, how much was the difference between walk and xform with that result?
Unfortuinely I don't have exact numbers. We also optimised the query at that time.
We also have very big query results.
To give a very rough idea about our postwalk approach vs a direct update fn;
(time
(do (map (fn [x] (update x :field :db/ident))
corpus)
nil))
"Elapsed time: 0.093924 msecs"
=> nil
(time
(do (walk/postwalk (fn [x]
(if (and (map? x)
(:db/ident x))
(:db/ident x)
x))
corpus)
nil))
"Elapsed time: 552.667018 msecs"
=> nil
(corpus is a list of 150,000 maps btw)interesting, thanks
but isnโt the first one not a good benchmark, as map returns lazy seq
You're absolutely right. I knew something was up.
(time
(do (mapv (fn [x] (update x :field :db/ident))
corpus)
nil))
"Elapsed time: 142.214586 msecs"
=> nil
For completionist sake:Thought I'd persist this question on ask.datomic so others can reference it and add their opinion: https://ask.datomic.com/index.php/606/recommended-way-to-handle-db-ident-enums-when-used-with-pull
one way i was doing this was to take my nested entity thats returned from the pull and then run it through a post-walk like so:
(clojure.walk/postwalk
#(match %
{:db/ident ident} ident
:else %)
nested-entity)
if you know that all maps with db/ident
are referencing enums you want to unwrapOh, nice! That's a pretty heavy penalty to pay for using enums as idents though.