This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-05-16
Channels
- # announcements (22)
- # beginners (4)
- # biff (4)
- # cider (5)
- # clerk (3)
- # clojure (28)
- # clojure-chennai (1)
- # clojure-europe (23)
- # clojure-gamedev (7)
- # clojure-korea (5)
- # clojure-madison (3)
- # clojure-my (1)
- # clojure-nl (1)
- # clojure-norway (49)
- # clojure-sweden (7)
- # clojure-uk (4)
- # clojuredesign-podcast (14)
- # clojurescript (10)
- # clr (5)
- # cursive (4)
- # datascript (17)
- # datomic (2)
- # events (1)
- # garden (1)
- # introduce-yourself (2)
- # jobs-discuss (14)
- # lsp (23)
- # malli (14)
- # missionary (9)
- # off-topic (109)
- # overtone (7)
- # polylith (5)
- # releases (5)
- # shadow-cljs (7)
- # sql (13)
- # testing (30)
- # xtdb (10)
- # yamlscript (44)
I have need to put UUIDs (as strings) on more or less every entity in my DataScript DB. they'll either be supplied by upstream data getting ingested into DataScript (easy enough) or for newly minted entities will get generated locally and included.
I'd be happy to use the UUID strings as entity IDs straight in DataScript but I https://github.com/tonsky/datascript/issues/168 that it's not currently possible to do that. (I don't care about storage, if that makes a difference.)
is there a way to auto-fill these at transaction time? I often transact big complicated maps with a mix of upserts and new entities nested all inside them, so it's not practical to know where all the new entities are. I can do (d/q '[:find ?e :in $ :where [?e _ _] [(missing $ ?e :my.ns/uuid)]] db)
after each transaction, I suppose.
You can totally store uuids, either as strings or as uuid type, just store them as an attributte
is there a slicker way to enforce them than editing all the code that inserts new entities, and adding a post-test fixture that checks for anything without one?
fair enough. thanks!
ive definitely had this need and i think niki talked about using uuids in a hypothetical datascript 2 https://tonsky.me/blog/datascript-2/
but yeah i just added them manually in all my transaction fns
What's the case where you're not sure if you should add a new uuid though? It sounds like you either have it provided from your data source, or you should add one.
It's that I'm sometimes not so clear in my code to build transactions whether this is an update or a new value.
I ended up putting in the necessary conditions by hand. I'm not thrilled about that, but there's not really a good alternative, and the set of functions adding and updating things is limited.
If you make the uuid unique on the schema, the entity will be up setter
Upsertted
So you can just transact your nested objects with uids in them directly: if the entity exists it will be a upsert, if it doesn't exist it will be an insert
(require '[datascript.core :as d])
;; :db/ident is already unique
(def schema {:children {:db/cardinality :db.cardinality/many
:db/valueType :db.type/ref}})
(def conn (d/create-conn schema))
(d/transact! conn [{:db/ident "uuid1"
:prop1 1}])
(d/touch (d/entity @conn [:db/ident "uuid1"]))
;; => {:prop1 1, :db/ident "uuid1", :db/id 1}
(d/transact! conn [{:db/ident "uuid1"
:prop2 2}])
(d/touch (d/entity @conn [:db/ident "uuid1"]))
;; => {:prop1 1, :prop2 2, :db/ident "uuid1", :db/id 1}
(d/transact! conn [{:db/ident "uuid1"
:children [{:db/ident "uuid2"
:prop1 1}
{:db/ident "uuid3"
:prop2 2}]}])
(d/touch (d/entity @conn [:db/ident "uuid1"]))
;; => {:children #{#:db{:id 2} #:db{:id 3}}, :prop1 1, :prop2 2, :db/ident "uuid1", :db/id 1}
(d/touch (d/entity @conn [:db/ident "uuid2"]))
;; => {:prop1 1, :db/ident "uuid2", :db/id 2}
(d/touch (d/entity @conn [:db/ident "uuid3"]))
;; => {:prop2 2, :db/ident "uuid3", :db/id 3}
I used to do this with a custom :block/uid
prop but I've since learned that :db/ident
seems to already be unique
you can also query directly for the unique prop with the ref lookup [:db/ident "whatever"]
on pull/entity/etc
yes, I'm familiar with that approach. it's working well, I was just wondering if there was a slick way to hook in to attach a UUID to every entity, or nearly every entity. it's working fine, so no worries now.