Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transacting API for Datomic

Certainly a dumb question, but hopefully should clear things up.

I am following along https://docs.datomic.com/on-prem/getting-started/transact-schema.html, and the step to transact the schema, in this tutorial, is

user=> (d/transact conn {:tx-data movie-schema})

However, when I try this, I get

ClassCastException clojure.lang.PersistentArrayMap cannot be cast to java.util.List  datomic.api/transact 

Instead, when I just do

(d/transact conn schema)

it works for me. Is the tutorial missing some subtlety here? Am I missing something? (the only difference is that I'm using the Free version instead of the Starter Pro version).

Edit: the initial version of this post mentioned the schema, but this is generally true for just adding new facts too (i.e. using {:tx-data foo} doesn't work, but just using foo does).

like image 749
agam Avatar asked Nov 04 '18 08:11

agam


2 Answers

I think the cause of your problem here is an inconsistency between the Peer API (in which transact accepts a list) and the Client API (in which transact accepts a map containing a :tx-data key). I suspect you tried to run your REPL commands in the REPL of a Peer process, whereas the tutorial you linked to expects you to run commands in the REPL of a Client process.

Why the inconsistency between Peers and Clients? Not being part of the Datomic team, I can only speculate:

  1. The Peer API was designed before the Client API historically, at which time the 'transaction requests as lists' format was sufficient
  2. When the Client API was designed, because of the more expensive nature of calling d/transact (I believe it incurs an additional I/O roundtrip from client to server), the authors left room for additional data in transaction requests (e.g for templating), hence the more extensible map-based format.
like image 59
Valentin Waeselynck Avatar answered Sep 25 '22 16:09

Valentin Waeselynck


You can see a working demo here: https://github.com/cloojure/tupelo-datomic

Just clone the repo and run the tests:

~/tupelo-datomic > lein test

lein test tst.tupelo-datomic._bootstrap

----------------------------------
   Clojure 1.9.0    Java 10.0.1
----------------------------------

lein test tst.tupelo-datomic.bond

lein test tst.tupelo-datomic.bond-query

lein test tst.tupelo-datomic.core

lein test tst.tupelo-datomic.find

lein test tst.tupelo-datomic.functionality

lein test tst.tupelo-datomic.quick-start
:using-local

Ran 17 tests containing 110 assertions.
0 failures, 0 errors.
~/tupelo-datomic > 

Regarding your specific question, I have only used :tx-data as a field from the output of Datomic operations. I have never used it as a field from input data. It is possible that the docs you reference are incorrect or out of date.

Here is an example (note the parens instead of curly braces):

https://github.com/cloojure/tupelo-datomic/blob/master/src/tupelo_datomic/core.clj#L540


For more detail, you can see the native Datomic function call as the output of the wrapper function new-attribute in the unit tests: https://github.com/cloojure/tupelo-datomic/blob/master/test/tst/tupelo_datomic/core.clj#L46

  (let [result (td/new-attribute
                 :weapon/type :db.type/keyword
                 :db.unique/value :db.unique/identity :db.cardinality/one :db.cardinality/many
                 :db/index :db/fulltext :db/isComponent :db/noHistory)]
    (is (s/validate datomic.db.DbId (:db/id result)))
    (is (wild-match? {:db/id          :* 
                      :db/ident       :weapon/type
                      :db/index       true 
                      :db/unique      :db.unique/identity
                      :db/noHistory   true
                      :db/cardinality :db.cardinality/many
                      :db/isComponent true
                      :db.install/_attribute :db.part/db
                      :db/fulltext    true 
                      :db/valueType   :db.type/keyword}
          result)))
like image 29
Alan Thompson Avatar answered Sep 25 '22 16:09

Alan Thompson