Fork me on GitHub

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:")
(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.5}]) ;=> 

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}])

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!


I have written my own fns to assert a possibly existing tree of data into the database.


I’m curious about datalog rules. Sometimes I have 4-5 rules with the same name, it’s not clear which one(s) are matching, and it’s a little tedious to debug. A more debuggable form might be to give each rule a distinct name and use an or clause for each case in the general rule. Is anyone aware of the performance implications of this approach?

Drew Verlee20:07:16

Would it be correct to say datomic employees forward chaining logic?

Joe Lane21:07:01

I don't think so

Joe Lane21:07:13

That would be a rules engine, if i'm not mistaken.

Drew Verlee21:07:34

Right, I meant to say backwards chaining :thinking_face: