为 Datomic 交易 API

Transacting API for Datomic

当然是个愚蠢的问题,但希望能解决问题。

我正在跟进 https://docs.datomic.com/on-prem/getting-started/transact-schema.html,在本教程中处理架构的步骤是

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

但是,当我尝试这个时,我得到了

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

相反,当我这样做时

(d/transact conn schema)

对我有用。本教程是否缺少一些细微之处?我错过了什么吗? (唯一的区别是我使用的是免费版,而不是 Starter Pro 版)。

编辑: 这个 post 的初始版本提到了模式,但这通常也适用于添加新事实(即使用 {:tx-data foo}不起作用,但仅使用 foo 就可以)。

您可以在此处查看工作演示:https://github.com/cloojure/tupelo-datomic

只需克隆 repo 和 运行 测试:

~/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 > 

关于您的具体问题,我只使用了 :tx-data 作为 Datomic 操作的 output 的字段。我从未将它用作 input 数据的字段。您引用的文档可能不正确或已过时。

这是一个例子(注意括号而不是大括号):

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


有关更多详细信息,您可以在单元测试中将本机 Datomic 函数调用视为包装函数 new-attribute 的输出: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)))

我认为您的问题的原因是 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 您与客户端进程的 REPL 中的 运行 命令之间的不一致。

为什么同行和客户之间不一致?不是 Datomic 团队的一员,我只能推测:

  1. 从历史上看,Peer API 是在 Client API 之前设计的,当时 'transaction requests as lists' 格式就足够了
  2. 在设计客户端 API 时,由于调用 d/transact 的成本更高(我相信它会导致从客户端到服务器的额外 I/O 往返),作者为交易请求中的额外数据留出空间(例如用于模板),因此基于地图的格式更具可扩展性。