I’m trying to do a nested upsert, but this doesn’t seem to be possible. I found one technique to do a nested insert, and I found a different technique to do a nested update, there doesn’t seem to be a technique that will do an insert or an update (upsert) depending on the state of the database. Is this correct?
Given the following schema
(def schema
[{:db/ident :day
:db/unique :db.unique/identity
:db/valueType :db.type/long
:db/cardinality :db.cardinality/one}
{:db/ident :metric/day
:db/unique :db.unique/identity
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one}
{:db/ident :rev
:db/valueType :db.type/double
:db/cardinality :db.cardinality/one} ])
;;And some setup
(require '[datomic.api :as d])
(def db-uri "datomic:mem://minimal-example")
(d/create-database db-uri)
(def conn (d/connect db-uri))
@(d/transact conn schema)
With an empty database, the following inserts 3 datoms
@(d/transact conn [{:metric/day {:day 3} :rev 1.4}])
When I want to do an update to the previously created entries, the following works:
@(d/transact conn [{:metric/day [:day 3] :rev 1.5}])
However the previous insert structure doesn’t and gives and error:
@(d/transact conn [{:metric/day {:day 3} :rev 1.6}])
;; :db.error/unique-conflict Unique conflict: :metric/day, value: 17592186045419
;; already held by: 17592186045418 asserted for: 17592186045422
So this last variation is only a way to do a nested insert not an update. If we try the nested update variation on an empty database this fails too:
@(d/transact conn [{:metric/day [:day 3] :rev 1.5}])
;; :db.error/not-an-entity Unable to resolve entity: [:day 3] in datom
;; [-9223301668109597810 :metric/day [:day 3]]
The more verbose version with tempid’s doens’t work either:
(let [day-id (d/tempid :db.part/user)]
@(d/transact conn [{:db/id day-id :day 3}
{:metric/day day-id
:rev 1.1}]))
Am I missing how upserting could work in this nested situation or is this a limitation of Datomic by design? Any help is greatly apreciated!