Получение идентификатора вставленного объекта в datomic?
После выполнения транзакции в datomic для вставки значения, как я могу использовать возвращаемое значение транзакции для получения идентификаторов любых созданных объектов?
Вот пример возвращаемого значения, которое я получаю после вставки:
#<[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 .....
Я могу видеть базовые данные... как я могу извлечь их значения?
Ответы
Ответ 1
Используйте d/resolve-tempid. Если бы вы выполняли транзакцию с одним объектом, работа с ним выглядела бы :tx-data
, но если ваша транзакция содержала более одного объекта, то вы не знали бы порядка, в котором они отображаются в :tx-data
.
Что вам нужно сделать, это предоставить временные идентификаторы вашим сущностям (перед их выполнением), используя либо (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.
Ответ 2
А, понял.
Мне пришлось отменить обещание Clojure, а затем я смог вытащить нужные значения:
(:e (second (:tx-data @(transact! conn query))))
Ответ 3
Написал быструю функцию, основанную на ответе a2ndrade. Именование не является идеальным, и я могу совершать идиоматические faux pas; предложения очень приветствуются.
(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
Ответ 4
В библиотеке Dupomic Tupelo есть функция (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 EID from the seq (destructuring)
]