Search code examples
datomic

Cannot transact data to my datomic database


I am using the Datomic client api com.datomic/local {:mvn/version "1.0.285"}

and clojure version org.clojure/clojure {:mvn/version "1.11.1"}

i am importing like this [datomic.client.api :as d]

I'm very new to datomic.

I'm having an issue with Datomic where transactions appear to succeed but no data is actually being written to the database. The schema seems to be present, but only transaction timestamps are being created. Here's a minimal test case that demonstrates the problem: `

(defn check-schema [conn]
  (let [user-id-schema (d/q '[:find (pull ?e [*])
                             :where [?e :db/ident :user/id]]
                           (d/db conn))
        user-email-schema (d/q '[:find (pull ?e [*])
                                :where [?e :db/ident :user/email]]
                              (d/db conn))
        user-token-schema (d/q '[:find (pull ?e [*])
                                :where [?e :db/ident :user/verification-token]]
                              (d/db conn))]
    {:user/id user-id-schema
     :user/email user-email-schema
     :user/verification-token user-token-schema}))

(deftest user-creation
  (testing "user-creation"
    (println "Schema check:" (check-schema conn))
    (let [user-id (random-uuid)
          email "[email protected]"
          token "123456"
          res (d/transact conn [{:user/id user-id
                                :user/email email
                                :user/verification-token token}])
          db-after (d/db conn)
          users (d/q '[:find ?e ?email
                      :where [?e :user/email ?email]]
                    db-after)]
      (println "Transaction tx-data:" (seq (:tx-data res)))
      (println "Database after transaction:" db-after)
      (println "Found users:" users)
      (is (not (empty? users))))))

here is my datomic configuration

{:datomic-client {:server-type :datomic-local
                  :system "test"}}

Here is the result of the schema check

#:user{:id [[#:db{:id 115, :ident :user/id, 
                  :valueType #:db{:id 54, :ident :db.type/uuid}, 
                  :cardinality #:db{:id 35, :ident :db.cardinality/one}, 
                  :unique #:db{:id 37, :ident :db.unique/value}}]], 
       :email [[#:db{:id 119, :ident :user/email, 
                    :valueType #:db{:id 23, :ident :db.type/string}, 
                    :cardinality #:db{:id 35, :ident :db.cardinality/one}, 
                    :unique #:db{:id 37, :ident :db.unique/value}}]], 
       :verification-token [[#:db{:id 120, :ident :user/verification-token, 
                                :valueType #:db{:id 23, :ident :db.type/string}, 
                                :cardinality #:db{:id 35, :ident :db.cardinality/one}, 
                                :unique #:db{:id 37, :ident :db.unique/value}}]]}

However, when I attempt to transact data:

  • The transaction appears to succeed
  • Only a transaction timestamp datom is created (#datom[13194139533331 50 #inst "2024-11-27T09:50:52.123-00:00" 13194139533331 true])
  • No user data is actually written
  • Queries return empty results

Things I've tried:

  • Different entity ID approaches (tempid, UUID, string identifiers)
  • Different transaction formats (map form, :db/add form)
  • Verifying schema installation
  • Writing to transaction entity
  • Using numeric tempids
  • Creating a basic attribute write test

I think the schema is definitely installed and visible, but no actual data writes succeed. Only transaction timestamps are being recorded. What am I missing? Why aren't my transactions creating any datoms besides the transaction timestamp?


Solution

  • Focus on this lines:

    res (d/transact conn [{:user/id user-id
                           :user/email email
                           :user/verification-token token}])
    db-after (d/db conn)
    

    d/transact in datomic.client.api requires a {:tx-data around the transaction Calling d/db immediately after d/transact, it will get a db before the transaction. To fix that:

    1. Add a tx-data to the transaction (d/transact conn {:tx-data [....]
    2. Get your db-after from the result of the transaction {:keys [db-after]} (d/transact

    Also a few tips:

    • Functions that query, like check-schema, should receive a db, not a conn.
    • it is possible to call (d/pull db '[*] :user/id) do pull the schema
    • Please clarify if you are using datomic.client.api or datomic.api. The com.datomic/local dependency provides the datomic.client.api. The client API uses this transact syntax: (d/transact conn {:tx-data [....]})