2013-06-19 2 views
12

Nachdem ich eine Transaktion in Datomic ausführen, um einen Wert einzufügen, wie kann ich den Rückgabewert der Transaktion verwenden, um die IDs von Entitäten zu erhalten, die erstellt wurden? HierErmitteln der ID einer eingefügten Entität in Datomic?

ist eine Probe des Rückgabewertes I nach einem Einsatz kommen:

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

Ich kann das zugrunde liegende datum sieht ... wie kann ich ihre Werte extrahiere?

Antwort

12

Verwendung. Wenn Sie eine einzige Entität abwickeln würden, würde die Suche nach :tx-data funktionieren, aber wenn Ihre Transaktion mehr als eine Entität enthielt, dann würden Sie die Reihenfolge nicht kennen, in der sie in :tx-data erscheinen.

Was Sie tun sollten, ist nur vorübergehend IDs Ihre Entitäten geben (vor ihnen Transaktionen) unter Verwendung von entweder (d/tempid) oder seiner wörtlichen Darstellung #db/id[:db.part/user _negativeId_] und dann d/resolve-tempid verwenden von temporären ID in die reale ID von der Datenbank gegeben zu gehen. Der Code würde in etwa so aussehen:

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

Für ein vollständiges Codebeispiel finden Sie in diesen gist.

+0

Ah süß, ich wusste, dass es einen idiomatischen Weg geben sollte, Dinge zu tun. Ich beschränkte meine Ansätze auf Funktionen, die garantierten, dass sie nur eine Entity einfügen würden, aber es ist wirklich nett, mit dem allgemeinen Fall umgehen zu können. – HaskellMan

+0

Ist '(d/transact conn [{: db/id" myentity ": etwas/attr 123}])' äquivalent zu '(d/tempid" myentity ")'? –

+0

Ich habe eine Situation, in der ich die Entity-ID vor dem Einfügen der Daten kennen muss, da ich diese ID woanders ablegen muss, bevor ich alle für das Einfügen notwendigen Daten bekomme (Normalerweise geschieht dies durch Transaktion in anderen Datenbanken) . Wäre der Tempid dafür nützlich? Die Tatsache, dass du eine tempid zu einer echten ID auflösen kannst, scheint zu bedeuten, dass ich später die tempid zu der echten ID ändern müsste. – CMCDragonkai

6

Ah, habe es herausgefunden.

Ich hatte das Clojure Versprechen, deref und dann die Werte ausreißen konnte ich mich wollte: d/resolve-tempid

(:e (second (:tx-data @(transact! conn query)))) 
1

Schrieb eine schnelle Funktion basierend auf a2ndrade's Antwort. Die Benennung ist nicht ideal und ich begehe vielleicht idiomatische Fauxpas; Vorschläge sind sehr willkommen.

(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)) 

Verwendungsbeispiel:

(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

sieht gut aus, Mann! also habe ich recht beim lesen, dass man die partition der tx map hinzufügen müsste? (passend zu: db/id)? – sova

+1

@sova Ein Beispiel hinzugefügt. Beantwortet das deine Frage? – deadghost

+0

Ja, das ist großartig. vielen Dank (= – sova

0

The Tupelo Datomic library hat eine Funktion (td/eids tx-result) leicht den Eid in einer Transaktion erstellt zu extrahieren. Zum Beispiel:

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