I have some doubts about datomic.api/tempid fn that provides entity id.
It produces some long value, not UUID String and long is 64 bit which makes me think about it's uniqueness after some point I might reach long's limit. It would be harder with UUID instead.
When I write some code like this, I ask myself "Does this reach the entity id limit and cause a problem when adding new entities?"
@(d/transact
conn
[{:db/id (d/tempid :db.part/user)
:city/district "BEYKOZ"}])
As the name suggests,
tempidonly provides a temporary identifier; these are to be used within the context of a single transaction. So you're not going to run out of IDs unless you exceed 2^64 new records within a single transaction—and that kind of transaction would be way too large to run anyway.The primary purpose of tempids is to allow us to reference newly-created entities in multiple places within a transaction.
In fact, the map-based transaction format is a shorthand for the vector-based format; if we want to create a city with a couple attributes, internally, Datomic is doing something more like:
...which is only possible with some kind of shared identifier, but we don't know the permanent, insert ID until we've round-tripped from the database.
Tempids also allow us a way to find these permanent IDs via the return value of
transact, by looking into a map of temp IDs to permanent IDs. e.g.It's also worth noting that as of Datomic 0.9.5530, you don't need to add tempids manually to new records (simply leave the
:db/idout of the map), and you can also use strings as tempids. So, for example, we could rewrite the city transaction as: