Получение идентификатора вставленного объекта в datomic?

После запуска транзакции в datomic для вставки значения, как я могу использовать возвращаемое значение транзакции для получения идентификаторов любых созданных объектов?

Вот пример возвращаемого значения, которое я получаю после вставки:

#<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 .....

Я вижу базовые данные... как я могу извлечь их значения?


person TG-T    schedule 19.06.2013    source источник


Ответы (4)


Используйте 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.

person a2ndrade    schedule 19.06.2013
comment
Ах, милый, я знал, что должен быть идиоматический способ делать вещи. В настоящее время я ограничивал свои подходы функциями, которые гарантировали, что они будут вставлять только один объект, но действительно приятно иметь возможность обрабатывать общий случай. - person TG-T; 19.06.2013
comment
Является ли (d/transact conn [{:db/id "myentity" :some/attr 123}]) эквивалентом (d/tempid "myentity")? - person Petrus Theron; 17.01.2018
comment
У меня есть ситуация, когда мне нужно знать идентификатор объекта до вставки данных, так как мне нужно поместить этот идентификатор в другое место, прежде чем я смогу получить все данные, необходимые для вставки (обычно это делается через транзакцию в других базах данных). Будет ли tempid полезен для этого. Тот факт, что вы можете преобразовать tempid в реальный идентификатор, по-видимому, означает, что позже мне придется изменить tempid на настоящий идентификатор. - person CMCDragonkai; 25.01.2018

А, разобрался.

Мне пришлось удалить промис Clojure, и тогда я смог получить нужные мне значения:

 (:e (second (:tx-data @(transact! conn query))))
person TG-T    schedule 19.06.2013

Написал быструю функцию на основе ответа 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
person deadghost    schedule 08.03.2015
comment
хорошо выглядишь, чувак! так что я прав, читая, что нужно будет добавить раздел на карту tx? (чтобы соответствовать :db/id)? - person sova; 09.03.2015
comment
@sova Добавил пример. Это отвечает на ваш вопрос? - person deadghost; 09.03.2015

Библиотека Tupelo Datomic имеет функцию (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)
  ]
person Alan Thompson    schedule 02.09.2015