Fork me on GitHub
#datomic
<
2020-03-10
>
kenny00:03:04

Should you type hint in Datomic queries? For example:

(d/q
  '[:find ?e ?mins
    :where
    [?e :my-date ?transition-date]
    [(.toInstant ?transition-date) ?i]
    [(.atZone ^java.time.Instant ?i (java.time.ZoneId/of "UTC")) ?zoned-dt]
    [(.toLocalDateTime ?zoned-dt) ?local-dt]
    [(.getMinute ?local-dt) ?mins]]
  (d/db conn))

jcf08:03:59

I might consider using a function of my own inside the query at this point. Something like (com.example.time/minutes ?transition-date).

favila11:03:25

You should type hint according to the same rules as Clojure

1
favila12:03:27

(So generally, yes, unless it’s throwaway code or type inference figured out the type already)

mruzekw21:03:37

Hi everyone, does using API Gateway HTTP Direct with Ions avoid any cold start up latency given it doesn’t involve a Lambda at all? Are there other latency trade-offs to consider? https://blog.datomic.com/2019/05/http-direct-for-datomic-cloud.html

Joe Lane21:03:51

Correct, no cold start.

Matheus Moreira21:03:40

hello! probably a datomic newbie situation here: i am not sure how to use (or if it is possible to use) a tuple attribute that models a natural composite key as the value of an attribute that is a ref. my situation is this: template-schema

[...
 {:db/ident :template/id
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/uuid
    :db/unique :db.unique/identity}
   {:db/ident :template/name
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/string}
   {:db/ident :template/provider
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/ref}
   {:db/ident :template/provider+name
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/tuple
    :db/tupleAttrs [:template/provider :template/name]
    :db/unique :db.unique/identity}
 ...]
infocard-schema
[...
 {:db/ident :infocard/id
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/uuid
    :db/unique :db.unique/identity}
   {:db/ident :infocard/user-id
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/uuid}
   {:db/ident :infocard/template
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/ref}
 ...]
i thought it would be possible to transact an infocard referring to an existing template like this:
(d/transact conn {:tx-data [#:infocard{...
                                       :template [:template/provider+name [:provider/engage "test-template]]
                                       ...}]})
but when i do this the result is unable to resolve entity. what am i doing wrong?

favila21:03:03

Composite attrs are not meant to be transacted directly, but computed automatically (otherwise they can get out of sync with their values)

favila21:03:13

that said, I haven’t personally been able to use an identity composite ref attribute in any way other than explicitly asserting tempids for the composite value and all its components. It appears that tempid resolution to existing entities occurs before composites are computed, (at least the last time I checked). In practice this means identity composites are not useful for upserting, only guaranteeing uniqueness (carefully)

favila21:03:59

I’d welcome some clarification on whether this is considered by-design and what one should do if an identity composite key is desired

favila21:03:31

(note what I’m doing contradicts the admonition “never transact composites directly”)

Matheus Moreira21:03:06

i my case i don’t assert the composite directly, the template already exists in the database and the composite was calculated by datomic itself.

Matheus Moreira21:03:57

after the template is there, i try to create an infocard referring to it but using the composite key as a unique id instead of the surrogate uuid because the composite key is what clients know.

Matheus Moreira21:03:29

(so my api receives the pair provider/name instead of the surrogate key when creating an infocard.)

favila22:03:33

Your transaction data as you are presenting it is asserting the composite, though

favila22:03:14

and by making it an identity attribute that strongly suggests you mean for this to be upserting

Matheus Moreira22:03:26

so this is the first flaw. 🙂 what i’d like to do is to refer to the template by its composite key.

favila22:03:18

if you don’t want to assert it, use it as a lookup ref (which I think should work now but earlier versions were buggy about): {:db/id [:template/provider+name [:provider/engage "test-template]] …}

Matheus Moreira22:03:46

ah, let me try that.

favila22:03:56

and probably weaken :db.unique/identity to :db.unique/value

favila22:03:06

Note using a lookup ref will fail if the entity doesn’t already exist, but your earlier transaction could succeed (if the lookups were resolved, that is)

Matheus Moreira22:03:15

what about queries? i should be able to fetch templates using :where [?e :template/provider+name [:provider/engage "test-template]] , right?

Matheus Moreira22:03:36

looking at the transaction grammar (https://docs.datomic.com/cloud/transactions/transaction-data-reference.html#orge639385) it seems that [attr value] should be a valid entity identifier, that is why i used that form trying to transact the infocard.

favila22:03:10

I think that syntax works in queries, but maybe you have to use tuple to assemble the value

favila22:03:51

my point about transact is that you are actually attempting to transact that attribute, not merely looking it up

favila22:03:36

transaction maps are merely sugar for [:db/add the-key the-value]