Fork me on GitHub
#datascript
<
2022-08-29
>
Drew Verlee18:08:44

Can someone else me understand why why transacting the same entity, because it has a shared :db.unique/value, unexpectedly results in a new entity (new db/id)? e.g

make value unique
(d/transact! conn [{:db/ident :db/uuid
                    :db/valueType :db.type/uuid
                    :db/cardinality :db.cardinality/one
                    :db/unique :db.unique/value}]) 


(def uuid (random-uuid))

;; inesrt into do
(d/transact! conn [{:entity/name "foo"
                    :db/uuid uuid}])

;; this should be an upsert now
(d/transact! conn [{:entity/name "bar"
                    :db/uuid uuid}])
But when i compare the db before and db after i see the entity "2" didn't change, instead there is a new one "3"
{:db-before
 #datascript/DB {:schema {},
                 :datoms
                 [[1 :db/cardinality :db.cardinality/one 536870913]
                  [1 :db/ident :db/uuid 536870913]
                  [1 :db/unique :db.unique/value 536870913]
                  [1 :db/valueType :db.type/uuid 536870913]
                  [2
                   :db/uuid
                   #uuid "aa5e8db5-3777-400b-9473-d921a4e6a494"
                   536870914]
                  [2 :entity/name "foo" 536870914]]},
 :db-after
 #datascript/DB {:schema {},
                 :datoms
                 [[1 :db/cardinality :db.cardinality/one 536870913]
                  [1 :db/ident :db/uuid 536870913]
                  [1 :db/unique :db.unique/value 536870913]
                  [1 :db/valueType :db.type/uuid 536870913]
                  [2
                   :db/uuid
                   #uuid "aa5e8db5-3777-400b-9473-d921a4e6a494"
                   536870914]
                  [2 :entity/name "foo" 536870914]
                  [3
                   :db/uuid
                   #uuid "aa5e8db5-3777-400b-9473-d921a4e6a494"
                   536870915]
                  [3 :entity/name "bar" 536870915]]},
 :tx-data
 [#datascript/Datom [3 :entity/name "bar" 536870915 true]
  #datascript/Datom [3
                     :db/uuid
                     #uuid "aa5e8db5-3777-400b-9473-d921a4e6a494"
                     536870915
                     true]],
 :tempids {3 3, :db/current-tx 536870915},
 :tx-meta nil}
Though if we query the db we get the expected result:
(d/q '[:find [?db-id ?name ?uuid]
       :where
       [?db-id :db/uuid ?uuid]
       [?db-id :entity/name ?name]]
     (d/db conn))
;; => [3 "bar" #uuid "aa5e8db5-3777-400b-9473-d921a4e6a494"]
Then confusingly, if i txt again with the same uuid, but a different name, i unexpectedly don't get the name updated:
(d/transact! conn [{:entity/name "cat"
                    :db/uuid uuid}])


(d/q '[:find [?db-id ?name ?uuid]
       :where
       [?db-id :db/uuid ?uuid]
       [?db-id :entity/name ?name]]
     (d/db conn))
;; => [3 "bar" #uuid "aa5e8db5-3777-400b-9473-d921a4e6a494"]
I'm trying to find docs specific to datascript, but as far as i can tell it should honor how datomic handles unique values right? Maybe I don't understand the contract. thanks in advance 🙂 :thumbsup:

hiredman18:08:24

I haven't used datascript a ton, but I believe you have to specify the schema upfront and cannot use transact! to add new attributes (:schema is empty in your output there)

Drew Verlee18:08:53

that's probably it. thanks a ton, that could have taken me a while to have noticed. 😌

Niki18:08:04

You need :db.unique/indentity for upserts, too

Drew Verlee18:08:53

i see that. interesting. thanks @U050UBKAA