在datomic中运行一个事务来插入一个值后,如何使用事务的返回值来获取所创建的任何实体的id?
以下是插入后得到的返回值的示例:
#<promise$settable_future$reify__4841@7c92b2e9: {:db-before datomic.db.Db@62d0401f, :db-after datomic.db.Db@bba61dfc,
:tx-data [#Datum{:e 13194139534331 :a 50
:v #inst "2013-06-19T11:38:08.025-00:00"
:tx 13194139534331 :added true} #Datum{:e 17592186045436 .....
我可以看到基础数据......如何提取其值?
答案 0 :(得分:12)
使用d/resolve-tempid。如果您要处理单个实体,查看:tx-data
会有效,但如果您的交易包含多个实体,那么您将不知道它们在:tx-data
中的显示顺序。
您应该使用(d/tempid)
或其文字表示#db/id[:db.part/user _negativeId_]
为您的实体提供临时ID(在进行交易之前),然后使用d/resolve-tempid
从您的临时ID转到数据库给出的真实id。代码看起来像:
(d/resolve-tempid (d/db conn) (:tempids tx) (d/tempid :db.part/user _negativeId_))
有关完整的代码示例,请参阅此gist。
答案 1 :(得分:6)
我不得不贬低Clojure的承诺,然后我能够掏出我想要的价值观:
(:e (second (:tx-data @(transact! conn query))))
答案 2 :(得分:1)
根据a2ndrade的答案写了一个快速的功能。命名并不理想,我可能会犯下惯用的失礼;建议非常受欢迎。
(ns my.datomic.util
(:require [datomic.api :as d]))
(defn transact-and-get-id
"Transact tx and return entity id."
[conn tx]
(let [tempid (:db/id tx)
post-tx @(d/transact conn [tx])
db (:db-after post-tx)
entid (d/resolve-tempid db (:tempids post-tx) tempid)]
entid))
使用示例:
(def my-conn
(d/connect (str "datomic:sql://datomic?jdbc:postgresql://"
"127.0.1:5432/datomic?user=datomic&password=somepw")
(defn thing-tx
"Create transaction for new thing."
[name]
{:db/id (d/tempid :db.part/user)
:thing/name name})
(transact-and-get-id my-conn (thing-tx "Bob")) ;; => 17592186045502
答案 3 :(得分:0)
The Tupelo Datomic library有一个函数(td/eids tx-result)
,可以轻松提取事务中创建的EID。例如:
; Create Honey Rider and add her to the :people partition
(let [tx-result @(td/transact *conn*
(td/new-entity :people ; <- partition is first arg (optional) to td/new-entity
{ :person/name "Honey Rider" :location "Caribbean" :weapon/type #{:weapon/knife} } ))
[honey-eid] (td/eids tx-result) ; retrieve Honey Rider's EID from the seq (destructuring)
]