Fork me on GitHub
#datascript
<
2016-07-19
>
jjunior13003:07:19

Can someone help me make Datomic schemas for use with DataScript? At least for the ones with => Schema for DataScript

(def Name
  Str)

(def FundamentalUnit
  (enum "K" "s" "bit" 
        "dollar" "cd" "kg" 
        "A" "m" "mol"))

(def FundamentalUnits
  {(conditional FundamentalUnit
                FundamentalUnit
                :else (enum "bits" "<<IMAGINARY_UNIT>>" "oz" 
                            "lb" "1000inch"))
   Int})

(def Unitless
  {})

(def Unit
  [Name {:v Num 
         :u (conditional empty?
                         Unitless
                         FundamentalUnits)}])

(def PhysicalQuantity
  {:amount pos?
   :unit Unit})

(def Transaction
  {(enum :production :consumption) PhysicalQuantity
   :timestamp DateTime})
=> Schema for DataScript

;; most important piece of data for what I'm working on.
(def TransactionHistory
  '(Transaction)) 
=> Schema for DataScript

(def Dimension
  [(conditional empty?
                Unitless
                FundamentalUnits) 
   Name])
The units are based on https://github.com/martintrojer/frinj/blob/master/resources/units.edn I'm studying to understand writing Datomic schemas.

tonsky07:07:18

@jjunior130: I don’t understand your syntax, can you show what you expect your data to look like?

jjunior13009:07:49

@tonsky: Was using the syntax of https://github.com/plumatic/schema The data would look something like:

;; List of transactions
(list 
  ;; Getting money
  {:production {:amount 15
                :unit ["USD" {:v 1 
                              :u {"dollar" 1}}]}
   :timestamp "01-03-2016"}

  ;; Spending money
  {:consumption {:amount 5
                 :unit ["USD" {:v 1 
                               :u {"dollar" 1}}]}
   :timestamp "01-08-2016"}

  ;; burning Calories
  {:consumption {:amount 500
                 :unit ["Calories" {:v 20934/5 
                                    :u {"m" 2, "s" -2, "kg" 1}}]}
   :timestamp "01-15-2016"}) ;; etc

tonsky09:07:23

so you need to model it as datoms?

tonsky09:07:12

do you have any particular problem or just don’t know where to start?

jjunior13009:07:04

Don't know where to start. I think I should start writing a Datomic schema for (datascript.core/create-conn <insert-schema>)

tonsky09:07:03

Do you have any prior experience with Datomic?

tonsky09:07:55

that explains basics of Datoms, DB structure and Datalog

jjunior13009:07:25

I saw that video, I'll rewatch it.

tonsky09:07:09

unfortunately, DataScript has no tutorials/docs at the moment, I recommend everybody to learn from Datomic resources instead

jjunior13009:07:56

Yeah that's what i've been doing lately. Reading http://docs.datomic.com/schema.html to learn writing the schema I need, if I even need a schema.

tonsky09:07:03

Your schema’d probably look something like that:

tonsky09:07:08

{ :production/amount {}
  :production/unit { :db/valueType :db.type/ref }
  :timestamp {}
  :consumption/amount {}
  :consumption/unit { :db/valueType :db.type/ref }
  :unit/name {}
  :unit/v {}
  :unit/u {} }

tonsky09:07:57

{ :production/amount {}
  :production/unit { :db/valueType :db.type/ref }
  :timestamp {}
  :consumption/amount {}
  :consumption/unit { :db/valueType :db.type/ref }
  :unit/name { :db/unique :db.unique/identity }
  :unit/v {}
  :unit/u {} }

tonsky09:07:11

I don’t know what :v and :u mean?

tonsky09:07:40

In DataScript, you only specify small subset of what you’d specify in Datomic

tonsky09:07:55

e.g. no types required beyond :db.type/ref

jjunior13009:07:09

:u is the dimension https://en.wikipedia.org/wiki/List_of_physical_quantities and :v is the factor to multiply by to get the SI Unit value

tonsky09:07:39

I see. You’re probably fine then with my second variant

tonsky09:07:54

also, unlike Datomic, you can put maps and vectors as values

tonsky09:07:26

so for your :unit/u you can just store is as a map

tonsky09:07:38

I see it has variable structure

jjunior13009:07:07

Nice, DataScript fits nicely with Specter then. https://github.com/nathanmarz/specter

jjunior13009:07:31

Thank you very much. This will help me a lot.

tonsky09:07:38

good! Do you know how to proceed? Transacting data, querying it?

tonsky09:07:53

there’re couple of sample apps I did back then

tonsky09:07:13

maybe looking into source code will clarify a thing or two

jjunior13009:07:21

yes, from what I understand datascript.core for transact and posh.reagent for querying.

tonsky09:07:42

also there’s a webinar where I build an app http://vimeo.com/114688970

jjunior13009:07:10

cool! will check them out. examples are good for reference.

dhucerbin09:07:10

posh also has transact and as I understand, it batches transactions across subscriptions lifecycle

jjunior13009:07:20

@dhucerbin: yeah you're right, I forgot about that

;; Posh's transact
(defn transact! [poshdb-or-conn txs]
  (datascript.core/transact!
   (if (datascript.core/conn? poshdb-or-conn)
     poshdb-or-conn
     (posh.stateful/poshdb->conn poshdb-or-conn))
   txs))