Fork me on GitHub
Brian Abbott15:12:13

Hey guys, does anyone have experience with pre-creating ids on Datomic, pre-transact?


As in, using UUID/randomUUID or d/squuid?

Brian Abbott16:12:09

I think Squuid — the idea is, for data hierarchies, solve for child elements in the tree prior to their being created such that, an element that is created, can be given its :db/id on the client, at the time that the data is available and, from that point on, assuming the transact operation fully succeeds, reliably know that on the client, at the time that that entities id was assoc’d into a hierarchy, it will forever be that entities id.


Do you mean specifically :db/id? You cannot control :db/id and applications should not rely on it being indefinitely stable (e.g. by storing it durably somewhere and using it as a reference)


generally people create a cardinality-one uuid attr with index-value or index-identity


then use that as the public id for their entities via lookup refs, e.g. [:my-public-id #uuid"…"] wherever they would normally use a raw :db/id


There’s some subtlely here about when you create these ids and whether you want them to be “upserting” (using indexed-identity). I’d have to know more about your problem to help further

👍 4
Dustin Getz19:12:07

Hyperfiddle uses tempids on the client, and then when the transaction returns we inspect the tx-report which contains a tempids map which maps the tempids to the realized ids, and then you can update your client state accordingly (for example if you have tempids in your url we can rewrite the url to the new id)

👍 4
Dustin Getz19:12:42

If this is not good enough for you, i’m interested in knowing what you’re doing that needs something different

👍 4
Brian Abbott16:01:47

I found a work around which…. it comes down to the way I wanted to do it originally but, I was inspired by some philisophical ideas I read (extrapolated) from the datomic docs plus how we’re writing some of our code as a result of the Lacinia/Datomic code but, let me get back to you guys - Im going to write a short ‘paper’ really a design req/solution ideas that, provided that our CTO okays it, i’ll send to anyone interested.

Brian Abbott16:01:55

The philosophy being that, I want to be able to throw into dat. a graph of arbitrary depth/complexity that, requires referential integrity at time of creation (client-side) in order to …. not force non-inuitive UI workarounds. (i.e. a sequential create step where ids are created on one screen to be able to provide to the next screen in the wizard but, it starts getting broken up purely to serve this necessity and not for the best/most-ideal UX)

Dustin Getz18:01:59

Graphs stitched with tempids do have referential integrity and 1:1 mapping to same graph post transact. Seems like I am missing something you’re saying


At the risk of causing confusion with @UFVRVT0L8’s original question, I'll raise what I think is the same challenge: I have client-side logging that adheres to a protobuf schema. One or more protobuf messages will get logged for a given user action, each message having a shared UUID generated by the client. This shared UUID enables connecting these messages as all related to the same user action. In the Datomic documentation it gives an example of entities shown as a table:


So, since I already have an ID for an "entity" in my data model, can I use that as the "E" column shown in this table above (a Datomic ident?) or is the entity ID only yielded from a transaction?


I think this is what @UFVRVT0L8 is asking too: If we have an ID created in a client-side process whose purpose is to connect related information to some entity in an implied data model, can we use that ID as the entity ID that automatically is indexed in Datomic?


I think the answer is Yes, given this section of the documentation, but I am only investigating Datomic and have no experience using it yet.


No, for a few reasons:


• Entity ids in a datom are primitive longs. You can’t use another type


• entity ids have an internal structure of partition and “t” or index. The index is guaranteed unique because of an internal counter the transactor advances


• entity ids are only created via the transactor “minting” an id (really advancing the counter and joining to a desired partition) from a tempid.


bottom line, entity ids are not meant to be something applications control. There used to be some partition control but even that ability is deprecated (and absent from datomic cloud)


That said, you should make your own :db.unique/identity or :db.unique/value attribute to attach your application’s notion of uniqueness e.g. via a uuid, and reference it via [:my-identity-attr value] lookup refs in your transaction data


Thanks @U09R86PA4, the use of :db.unique/identity seems to be the direction to go. I'll need to read more to understand how this identity would be indexed and used in graph queries.