Fork me on GitHub
#datomic
<
2019-02-12
>
johanatan00:02:13

each time there is a transaction, a new one replaces the existing one

favila00:02:40

It looks here like you have one ?und per ?sym

johanatan00:02:57

yes, correct. and many :quotes per ?und

favila00:02:25

why do you expect many tx if you have only one und per sym?

johanatan00:02:50

because many calls to transact for that und/sym pair are occuring

johanatan00:02:56

roughly one every 10 minutes

johanatan00:02:09

the database is also growing so that "history" is there somewhere

favila00:02:29

assertions which don't change the value that is there already do not add datoms

johanatan00:02:48

oh, gotcha. in this case, the price is the part that should be changing

favila00:02:17

if :my-attr is card-one, [:db/add 123 :my-attr "my-value"] will only add a datom the first time

johanatan00:02:20

hmm, so perhaps i need ?tx on the :price and the :time attrs to tie these together

favila00:02:56

why are you joining on tx?

johanatan00:02:15

because i want the data to be consistent per some point in time

johanatan00:02:19

i.e., the tx

johanatan00:02:21

tx is a synch point

favila00:02:46

your data is consistent by virtue of your DB value

johanatan00:02:05

if these were one entity rather than two, no need for join

johanatan00:02:31

but since it is split into two related entities, i need to fix them to the same point in time no ?

johanatan00:02:23

yes, this worked!

johanatan00:02:34

the answer was:

(def price-history-for-underlying
  '[:find ?price ?time ?tx
    :with ?q ?und
    :in $ ?sym
    :where
    [?und :underlying/symbol ?sym]
    [?und :underlying/price ?price ?tx]
    [?q :quote/underlying ?und]
    [?q :quote/time ?time ?tx]])

johanatan00:02:52

i am now getting all prices across all time

favila00:02:07

[?und :underlying/price ?price ?tx]

favila00:02:16

I don't understand this

johanatan00:02:44

it ensures that the ?und and the ?q that we select are "paired" together/, married together if you will, at a single point in time, namely at ?tx point in time.

favila00:02:06

is $ a history db or an ordinary db?

favila00:02:52

this will included retractions too

favila00:02:13

:underlying/price is cardinality-one and you keep writing over it?

favila00:02:19

or is it cardinality-many?

johanatan00:02:28

yea, it's one

johanatan00:02:31

and yea keep writing over it

favila00:02:48

so, if your price doesn't change from one-tx to the next, then you won't join

favila00:02:02

the TX of the price will be from the previous tx

johanatan00:02:02

i only care when prices actually change

johanatan00:02:34

so it will effectively just "skip" over those

favila00:02:56

it's conventional to mark history databases with $h since they usually change the nature of a query substantially

favila00:02:02

instead of just $

favila00:02:36

you should also probably include true to ensure you are only matching assertions

favila00:02:50

history dbs also include retractions

favila00:02:15

In this case set-wise results will make it all work out but it's easy to imagine getting surprised by duplicates with some query changes

johanatan00:02:31

hmm, what is a "retraction" in this context? like a deletion?

johanatan00:02:36

btw, $h isn't working for me. it says "did you forget to pass a database?"

johanatan00:02:42

but just $ works fine

favila00:02:56

you put $h in front of every caluse

favila00:02:03

[$h ?e ?a ?v]

favila00:02:09

retraction is a deletion yes

favila00:02:51

you can use d/datoms to see the actual stuff these clauses are matching against

favila00:02:03

if you use a history db, you will notice some datoms that end with "false"

favila00:02:09

those are retractions

m_m_m13:02:56

Hi. What I have to do to "update" my item in Datomic database and not add another one?

benoit13:02:34

@m_m_m Your transaction must include one of the attribute that identifies the entity you want to update. https://docs.datomic.com/on-prem/identity.html

superancetre13:02:19

Hi, I'm having trouble finding which dependency to add to my project.clj to complete the dev setup

superancetre13:02:33

notably requiring datomic.api like (require '[datomic.api :as d])

superancetre13:02:53

In the getting started the dependency is [com.datomic/client-pro "0.8.28"]

superancetre13:02:30

but it doesnt work when using (require '[datomic.api :as d]), any pointer please?

marshall19:02:54

the peer library needs to be in your deps.edn project.clj or maven pom file

superancetre14:02:58

Also doing bin\maven-install then mvn install:install-file -DgroupId=com.datomic -DartifactId=datomic-pro -Dfile=datomic-pro-0.9.5786.jar -DpomFile=pom.xmlgenerate an error

superancetre14:02:54

my bad on windows you have to escape things, so the correct command is mvn install:install-file -DgroupId="com.datomic" -DartifactId="datomic-pro" -Dfile="datomic-pro-0.9.5786.jar" -DpomFile="pom.xml"

danieroux14:02:11

I'm on cloud: export DATOMIC_ENV_MAP="{:env :local}" (ion/get-env) => "{:env :local}" ... it does not get read as EDN. What am I missing?

danieroux14:02:07

Ah. repl: export DATOMIC_ENV_MAP={:env :local}

danieroux14:02:31

And not: repl: export DATOMIC_ENV_MAP="{:env :local}" ... Makefiles are weird.

johanatan20:02:32

does anyone know how to use a java.util.Date instance in a predicate expression clause: e.g.,

[(<= ?time $before)]
when $before is an instance of java.util.Date, I get the following error: ClassCastException java.base/java.util.Date cannot be cast to clojure.lang.Symbol clojure.lang.Symbol.compareTo (Symbol.java:105)

favila13:02:01

Huh I just use the operators all the time. Where is $before from? It is named like a db

johanatan05:02:56

Oops, typo. ?before

johanatan05:02:23

Interestingly enough it seemed to work with vars named that way

johanatan05:02:29

Maybe it's just convention

johanatan20:02:47

ah, i think i need .before

misha21:02:02

Not actually a spec/datomic question, but closely related. Do you have any tricks to alleviate some pain of "broken sugar" for long namespaces of a

... Datomic ident style naming convention where :datomic.client.protocol/response enumerated values are like :datomic.client.protocol.response/body, which breaks the sugar
other than "suck it up"? This often eliminates most of let map destructuring too. (from this short sub-thread: https://www.reddit.com/r/Clojure/comments/8ousfs/namespaced_keywords_question/e0844vk)

benoit21:02:12

Namespaces are usually the solution to this. Clojure uses them. XML too. I have no idea if this notion of namespace will come to spec though.

benoit21:02:02

But no I have no trick except to not do that for every single piece of data inside your system 🙂

misha21:02:26

not sure what do you mean, @me1740. like "ns declared in some header"?

benoit21:02:41

Global names make the most sense for public interfaces.

benoit21:02:07

Yes, I meant a mechanism to declare the namespace for a given context.

lilactown21:02:26

the problem is that key namespaces don’t compose with the normal keyword operations. you can’t derive :datomic.client.protocol.response.error/status directly from :datomic.client.protocol.response/error

5
misha21:02:27

yeah, but as soon as you have several origins for the "same" key-val, having short implicit ns for your app key, and long global ns for external key – is kinda eew e.g.: :myapp/email and :oauth2.gmail/email (assuming ofc gmail ns would be much longer :) )

misha21:02:45

yeah, this is probably what I'm fishing for, @lilactown. some approach to juggle these "hierarchical"-but-not-really keywords

misha21:02:54

which does not break various destructuring sites, go-to-spec-definition in IDEs, etc. along the way

lilactown21:02:47

yeah. you can probably come up with a clever helper function for your s/def’s, but it falls over when trying to destructure

misha21:02:07

speaking of destructuring: as soon as you have :foo/id and :bar/id in the same map – you often have to go w/o destructuring too :(

lilactown21:02:46

yeah. it’s really annoying how destructuring completely loses the keyword ns. merging maps is easy but tearing off data requires more work

misha21:02:14

which, I hate to admit, makes :foo-id and :bar-id more appealing.

lilactown21:02:27

I usually end up doing something like:

{foo-id :foo/id bar-id :bar/id} big-map

misha21:02:26

which often longer than just (:bar/id big-map) once later in the fn

lilactown21:02:17

well, I usually like tear off all my data in one place. but yes, it’s not exactly pushing us into the pit of success

misha21:02:35

and is "naming same things over and over again" which Rich hates so much in java signatures and pattern matching

misha21:02:22

which brings us back to forms explosion, when keyword's ns is long enough (take any from https://gist.github.com/dustingetz/e3d0650d903d95ffe1cab1b343cfa073 from same reddit thread): :datomic.client.protocol.response/error

misha21:02:14

from short and sweet hello world form to enterprise in 2 seconds opieop

😭 5
misha21:02:10

also clojurescript does not have the alias fn (?)