1

I'm persisting an entity to Datomic, and I can pull it back out as expected. The entity has a unique UUID field :student/id, and if I try to query with a match on that field's value, I'm not getting results back. What am I doing wrong?

(require '[datomic.api :as d])

(def uri "datomic:mem://db")

(d/create-database uri)

(def conn (d/connect uri))
(def db (d/db conn))

(def schema
  [;; students
   {:db/ident :student/uuid1
    :db/valueType :db.type/string
    :db/cardinality :db.cardinality/one}
   {:db/ident :student/last
    :db/valueType :db.type/string
    :db/cardinality :db.cardinality/one}
   {:db/ident :student/id
    :db/valueType :db.type/uuid
    :db/cardinality :db.cardinality/one
    :db/unique :db.unique/identity}
   ])

(d/transact conn schema)

;; students

(def brandon {:student/id (d/squuid)
              :student/uuid1 "Brandon"
              :student/last "Smith"})

(def brandon-tx (d/transact conn [brandon]))
(def new-db (:db-after @brandon-tx))

@(def uuid1 (:student/id brandon))
;; ==>#uuid "64ce962a-e750-4d5e-a7eb-c860156ee8d0"
@(def uuid2 (-> (d/q '[:find (pull ?e [*])
                       :where [?e :student/id]] new-db) ffirst :student/id))
;; ==>#uuid "64ce962a-e750-4d5e-a7eb-c860156ee8d0"

(= uuid2 uuid1)
;; => true

;; I'm expecting to get Brandon back here, but I get an empty set
(d/q '[:find ?e
       :where [?e :student/id uuid1]] new-db)
;; => #{}
  • The quote on the last line is probably tripping you up, you're passing the symbol `first` into the query where (iiuc) you probably want a uuid... Maybe your query needs an input? https://docs.datomic.com/pro/query/query.html#inputs – Harold Aug 05 '23 at 19:35
  • A second comment: `first` and `second` are not great symbol names to choose here, because they already refer `clojure.core/first` and `clojure.core/second`, which makes your code confusing to read. (: – Harold Aug 05 '23 at 19:39
  • 1
    @Harold gah, I realized first and second were Clojure functions and thought I could edit before anyone noticed.. doh. You were right though, a query input fixed the problem. I don't really get when it's needed vs when it isn't, sometimes literal values work in queries but other times not, the correct literal UUID didn't work here either when I tried it.. In any case, `(d/q '[:find ?e :in $ ?uuid :where [?e :student/id ?uuid]] new-db (:student/id brandon))` worked for me, if you give your help as an answer I will accept it, thank you – Unsatisfied Zebra Aug 05 '23 at 19:47
  • 1
    Yup. Understanding what the quote is doing there will help answer the question of the relationship between the inputs and the literals... Here are a couple things you could read https://clojuredocs.org/clojure.core/quote and https://clojure.org/reference/special_forms#quote and (perhaps) https://stackoverflow.com/questions/134887/when-to-use-or-quote-in-lisp – Harold Aug 05 '23 at 21:39

1 Answers1

1

This is exactly what "inputs" are for, in Datomic queries.

Here is a link to the relevant documentation:

hth

Harold
  • 1,584
  • 1
  • 12
  • 20