-
Notifications
You must be signed in to change notification settings - Fork 312
Closed
Description
Upserting by unique composite tuple doesn't work in Datascript as it does in Datomic.
It was not immediately clear to me how to upsert by unique composite tuple in Datomic by the documentation, but I found this forum post about it:
https://forum.datomic.com/t/db-unique-identity-does-not-work-for-tuple-attributes/1072
The key part is the last post by jaret:
If you do want to identify an entity by a unique key, you must indeed specify that unique key (not its constituents).
Datascript:
(ns ds.core
(:require [datascript.core :as ds]))
;;
;; Upsert by Unique Composite Tuple
;;
(let [schema {:one+two {:db/tupleAttrs [:one :two]
:db/unique :db.unique/identity}}
conn (ds/create-conn schema)]
(ds/transact! conn [{:db/id "tmpid"
:one+two ["one" "two"]
:one "one"
:two "two"}
{:db/id "tmpid"
:one+two ["one" "two"]
:one "one"
:two "two"}])
(ds/transact! conn [{:db/id "tmpid"
:one+two ["one" "two"]
:one "one"
:two "two"}
{:db/id "tmpid"
:one+two ["one" "two"]
:one "one"
:two "two"}])
(ds/q '[:find [(pull ?e [*]) ...]
:where
[?e :one _]]
@conn))Gives this error:
Unhandled clojure.lang.ExceptionInfo
Can’t modify tuple attrs directly: [:db/add 1 :one+two ["one" "two"]]
{:error :transact/syntax, :tx-data [:db/add 1 :one+two ["one" "two"]]}
But in Datomic, this works:
(ns ds.datomic
(:require [datomic.client.api :as d]))
(let [client (d/client {:server-type :dev-local :system "dev"})]
(d/delete-database client {:db-name "tuples"})
(d/create-database client {:db-name "tuples"})
(let [conn (d/connect client {:db-name "tuples"})
schema [{:db/ident :one
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :two
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}
{:db/ident :one+two
:db/valueType :db.type/tuple
:db/tupleAttrs [:one :two]
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity}]]
(d/transact conn {:tx-data schema})
(d/transact conn {:tx-data [{:db/id "tmpid"
:one "one"
:two "two"
:one+two ["one" "two"]}
{:db/id "tmpid"
:one "one"
:two "two"
:one+two ["one" "two"]}]})
(d/transact conn {:tx-data [{:db/id "tmpid"
:one "one"
:two "two"
:one+two ["one" "two"]}
{:db/id "tmpid"
:one "one"
:two "two"
:one+two ["one" "two"]}]})
(d/q '[:find (pull ?e [*])
:where
[?e :one _]]
(d/db conn))))Yields:
[[{:db/id 79164837199948,
:one "one",
:two "two",
:one+two ["one" "two"]}]]
Metadata
Metadata
Assignees
Labels
No labels