Clojure 在datomic中获取插入实体的id?

Clojure 在datomic中获取插入实体的id?,clojure,datomic,Clojure,Datomic,在我在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:

在我在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 .....
啊,算了吧

我必须放弃Clojure的承诺,然后我才能拿出我想要的价值观:

 (:e (second (:tx-data @(transact! conn query))))
使用。如果您要处理单个实体,查看
:tx数据
是可行的,但如果您的交易包含多个实体,则您不知道它们在
:tx数据
中的显示顺序

您应该做的是使用
(d/tempid)
或其文字表示形式
#db/id[:db.part/user _negativeId][/code>为您的实体提供临时id(在进行交易之前),然后使用
d/resolve tempid
将临时id转换为数据库提供的真实id。代码将类似于:

(d/resolve-tempid (d/db conn) (:tempids tx) (d/tempid :db.part/user _negativeId_))

有关完整的代码示例,请参见此。

根据安德拉德的答案编写了一个快速函数。命名不理想,我可能犯了惯用的错误;欢迎提出建议

(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
具有一个功能
(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)
  ]
;创建Honey Rider并将其添加到:people分区
(让[tx结果@(td/transact*conn*

(td/new entity:people;啊,sweet,我知道应该有一种惯用的方法来做事情。我目前将我的方法限制在保证它们只插入一个实体的函数上,但是能够处理一般情况真的很好。是
(d/transact-conn[{:db/id“myentity”:some/attr 123}])
相当于
(d/tempid“myentity”)
?在插入数据之前,我需要知道实体id,因为我需要将该id放在其他地方,然后才能获得插入所需的所有数据(通常通过其他数据库中的事务完成)。tempid对此有用吗。您可以将tempid解析为真实id的事实似乎意味着我以后必须将tempid更改为真实id。看起来不错,伙计!我读到的关于必须将分区添加到tx映射的内容正确吗?(与:db/id匹配)?@sova添加了一个示例。这回答了您的问题吗?