2013-06-19 48 views
12

在我在datomic中運行一個事務來插入一個值後,如何使用事務的返回值來獲取創建的任何實體的ID?獲取datomic中插入實體的ID?

這裏是返回值插入後,我得到的一個樣本:

#<[email protected]: {:db-before [email protected], :db-after [email protected], 
:tx-data [#Datum{:e 13194139534331 :a 50 
:v #inst "2013-06-19T11:38:08.025-00:00" 
:tx 13194139534331 :added true} #Datum{:e 17592186045436 ..... 

我可以看到下面的基準...我怎麼能提取他們的價值觀?

回答

12

使用d/resolve-tempid。如果您要進行單個實體的交易,則可以使用:tx-data,但如果您的交易包含多個實體,則您不知道它們在:tx-data中的顯示順序。

你應該做的是給臨時ID,以你的實體(交易之前)使用或者(d/tempid)或它的文字表示#db/id[:db.part/user _negativeId_]然後用d/resolve-tempid從你的臨時身份去由數據庫提供的真實身份。該代碼看起來是這樣的:

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

對於一個完整的代碼示例,看到這個gist

+0

啊甜,我知道應該有一種慣用的方式來做事情。我目前正在將自己的方法限制在保證只能插入一個實體的函數上,但能夠處理一般情況真的很不錯。 – HaskellMan

+0

是'(d/transact conn [{:db/id「myentity」:some/attr 123}])'相當於'(d/tempid「myentity」)'? –

+0

我有一種情況,在插入數據之前需要知道實體ID,因爲我需要將該ID放在別的地方纔能獲取插入所需的所有數據(通常這是通過其他數據庫中的事務完成的) 。這個tempid是否有用。事實上,你可以將tempid解析爲真實的id,這似乎意味着我稍後必須將tempid改爲真實的id。 – CMCDragonkai

6

啊,算出來了。

我不得不DEREF Clojure的承諾,然後我能夠抽出了我想要的值:

(:e (second (:tx-data @(transact! conn query)))) 
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 
+0

看起來不錯,男人!所以我正確地閱讀那個人將不得不將分區添加到tx地圖? (以匹配:db/id)? – sova

+1

@sova新增了一個例子。這是否回答你的問題? – deadghost

+0

是的,太棒了。非常感謝(= – sova

0

The Tupelo Datomic library具有如下功能:向(td/eids tx-result)容易地提取在一個事務中創建的新發傳染病。例如:

; 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) 
    ]