【问题标题】:Transacting API for DatomicDatomic 交易 API
【发布时间】:2018-11-04 08:37:46
【问题描述】:

当然是个愚蠢的问题,但希望能把事情弄清楚。

我正在关注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 版)。

编辑:这篇文章的初始版本提到了架构,但这通常也适用于添加新的事实(即使用 {:tx-data foo} 不起作用,而只是使用 foo确实)。

【问题讨论】:

  • 我注意到另一个不一致的地方:虽然我的玩具示例现在可以工作(耶),但结果是哈希集,而教程中的结果是向量;不知道该怎么做。

标签: clojure datomic


【解决方案1】:

我认为您的问题的原因是Peer API(其中transact 接受列表)和Client API(其中transact 接受包含:tx-data 键的映射)之间的不一致.我怀疑您试图在 Peer 进程的 REPL 中运行您的 REPL 命令,而您链接到 expectstutorial 您是在客户端进程的 REPL 中运行命令。

为什么 Peers 和 Client 之间的不一致?不是 Datomic 团队的一员,我只能推测:

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

【讨论】:

  • 有道理!我不确定为什么我最终进入了“错误”过程的 REPL,但这可以解释我观察到的不一致。
  • 感谢您解释造成差异的可能原因!对于初学者来说,错误信息相当难以理解。
【解决方案2】:

您可以在此处查看工作演示: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 操作的 输出 的字段。我从未将它用作 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)))

【讨论】:

  • 谢谢,我的(令人惊讶的?)结论是一切正常(并且运行良好!)但文档已经过时了。
猜你喜欢
  • 2017-02-10
  • 1970-01-01
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多