Fixing a datomic anomalie - clojure

I was playing around with my datomic database. I think I got my database corrupted, I'm not sure where to begin for debugging or fixing the state of my database
When I try to run my app
(def cfg {:server-type :peer-server
:access-key "myaccesskey"
:secret "mysecret"
:endpoint "localhost:8998"
:validate-hostnames false})
(def client (d/client cfg))
(def conn (d/connect client {:db-name "pensine"}))
(def o11-schema [
{:db/ident :trip/name}
{:db/valueType :db.type/string}
{:db/cardinality :db.cardinality/one}])
It fails with this error
Caused by: clojure.lang.ExceptionInfo: Missing :db/ident for {:db/id 75, :db/valueType 23} {:cognitect.anomalies/category :cognitect.anomalies/incorrect, :cognitect.anomalies/message "Missing :db/ident for {:db/id 75, :db/valueType 23}", :entity {:db/id 75, :db/valueType 23}, :db/error :db.error/attribute-ident-missing, :dbs [{:database-id "datomic:dev://localhost:4334/pensine", :t 1011, :next-t 1012, :history false}]}

I've put the schema in three different maps by mistake, this is the fix:
[{:db/ident :trip/name
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one}]

Related

In Datomic, how to add new entities (as references) to the many attribute of an existing entity

By way of example I'm going to use a drawing as the existing entity which is to have two new shapes added to it. This is the tx that is failing:
[{:shape/id "BKF806TXXTAFWII0", :db/id "22NF08ZVGH9N7QGG_0"}
{:shape/id "YKIZU4CJC0JXJKVQ", :db/id "22NF08ZVGH9N7QGG_1"}
[:db/add 17592186047451 :drawing/shapes ["22NF08ZVGH9N7QGG_0" "22NF08ZVGH9N7QGG_1"]]]
As you can see the existing drawing has :db/id of 17592186047451. I'm trying to create two new shapes and add them to the cardinality many attribute :drawing/shapes. "22NF08ZVGH9N7QGG_0" and "22NF08ZVGH9N7QGG_1" are tempids that are supposed to be translated to the same new :db/ids wherever they appear.
I should say that the drawing doesn't have any existing shapes. If it did I would expect them to be orphaned.
This is the error message I'm getting:
Execution error (ExceptionInfo) at datomic.client.api.async/ares (async.clj:58).
Cannot interpret as a keyword: 22NF08ZVGH9N7QGG_0, no leading :
Something similar I've also tried:
[{:shape/id "9HTL5BMMHT6QUJM6", :db/id "22NF08ZVGH9N7QGG_0"}
{:shape/id "O5UB9IG9UB8KDVA2", :db/id "22NF08ZVGH9N7QGG_1"}
[:db/add 17592186047451 :drawing/shapes "22NF08ZVGH9N7QGG_0"]
[:db/add 17592186047451 :drawing/shapes "22NF08ZVGH9N7QGG_1"]]
Gives this error message:
Execution error (ExceptionInfo) at datomic.client.api.async/ares (async.clj:58).
Two datoms in the same transaction conflict
{:d1
[17592186047451 :drawing/shapes 17592186049126 13194139538021 true],
:d2
[17592186047451 :drawing/shapes 17592186049127 13194139538021 true]}
This gives the same error message as the first attempt:
[{:db/id 17592186047451, :drawing/shapes ["22NF08ZVGH9N7QGG_0" "22NF08ZVGH9N7QGG_1"]}
{:shape/id "3DZYWHEPQIAELF25", :db/id "22NF08ZVGH9N7QGG_0"}
{:shape/id "GJ804SOOU36YQX6Y", :db/id "22NF08ZVGH9N7QGG_1"}]
Getting rid of the tempids by doing it in a nested way:
[{:db/id 17592186047451,
:drawing/shapes
[{:shape/id "GEMRMRFG0E6N262M"}
{:shape/id "HTH2C7R90BQFFNXT"}]}]
Just yields this error message:
Execution error (ExceptionInfo) at datomic.client.api.async/ares (async.clj:58).
Unable to resolve entity: {:shape/id "GEMRMRFG0E6N262M"}
Your second example
[{:shape/id "9HTL5BMMHT6QUJM6", :db/id "22NF08ZVGH9N7QGG_0"}
{:shape/id "O5UB9IG9UB8KDVA2", :db/id "22NF08ZVGH9N7QGG_1"}
[:db/add 17592186047451 :drawing/shapes "22NF08ZVGH9N7QGG_0"]
[:db/add 17592186047451 :drawing/shapes "22NF08ZVGH9N7QGG_1"]]
and third example
[{:db/id 17592186047451, :drawing/shapes ["22NF08ZVGH9N7QGG_0" "22NF08ZVGH9N7QGG_1"]}
{:shape/id "3DZYWHEPQIAELF25", :db/id "22NF08ZVGH9N7QGG_0"}
{:shape/id "GJ804SOOU36YQX6Y", :db/id "22NF08ZVGH9N7QGG_1"}]
should work. Perhaps your :drawing/shapes attribute is not :db.cardinality/many?

Clojure nested json response

I am new to clojure and I am trying to make a simple API with 3 endpoints.
I am trying to implement an endpoint which will take each row of a query and put it to a json.
So I have an SQLite database. These are my entries for example:
{:timestamp 2020-09-11 14:29:30, :lat 36.0, :long 36.0, :user michav}
{:timestamp 2020-09-11 14:31:47, :lat 36.0, :long 36.0, :user michav}
So I want a json response like the below:
{:get
:status 200
:body {:timestamp "2020-09-11 14:29:30"
:lat 36.0
:long 36.0
:user "michav"}
{:timestamp "2020-09-11 14:31:47"
:lat 36.0
:long 36.0
:user "michav"}
}
}
Here is my code that I am trying to fix it in order to get the above result.
(def db
{:classname "org.sqlite.JDBC"
:subprotocol "sqlite"
:subname "db/database.db"
})
(defn getparameter [req pname] (get (:params req) pname))
(defn output
"execute query and return lazy sequence"
[]
(query db ["select * from traffic_users"]))
(defn print-result-set
"prints the result set in tabular form"
[result-set]
(doseq [row result-set]
(println row)))
(defn request-example [req]
(response {:get {:status 200
:body (-> (doseq [row output]
{:timestamp (getparameter row :timestamp) :lat (getparameter row :lat) :long (getparameter row :long) :user (getparameter row :user)} ))
}}))
(defroutes my_routes
(GET "/request" [] request-example)
(route/resources "/"))
(def app (-> #'my_routes wrap-cookies wrap-keyword-params wrap-params wrap-json-response))
The error I encounter is the following :
java.lang.IllegalArgumentException: Don't know how to create ISeq from: mybank.core$output
RT.java:557 clojure.lang.RT.seqFrom
RT.java:537 clojure.lang.RT.seq
core.clj:137 clojure.core/seq
core.clj:137 clojure.core/seq
core.clj:65 mybank.core/request-example[fn]
core.clj:65 mybank.core/request-example
core.clj:63 mybank.core/request-example
response.clj:47 compojure.response/eval1399[fn]
response.clj:7 compojure.response/eval1321[fn]
core.clj:158 compojure.core/wrap-response[fn]
core.clj:128 compojure.core/wrap-route-middleware[fn]
core.clj:137 compojure.core/wrap-route-info[fn]
core.clj:146 compojure.core/wrap-route-matches[fn]
core.clj:185 compojure.core/routing[fn]
core.clj:2701 clojure.core/some
core.clj:2692 clojure.core/some
core.clj:185 compojure.core/routing
core.clj:182 compojure.core/routing
RestFn.java:139 clojure.lang.RestFn.applyTo
core.clj:667 clojure.core/apply
core.clj:660 clojure.core/apply
core.clj:192 compojure.core/routes[fn]
Var.java:384 clojure.lang.Var.invoke
cookies.clj:171 ring.middleware.cookies/wrap-cookies[fn]
keyword_params.clj:32 ring.middleware.keyword-params/wrap-keyword-params[fn]
params.clj:57 ring.middleware.params/wrap-params[fn]
json.clj:42 ring.middleware.json/wrap-json-response[fn]
Var.java:384 clojure.lang.Var.invoke
reload.clj:18 ring.middleware.reload/wrap-reload[fn]
stacktrace.clj:17 ring.middleware.stacktrace/wrap-stacktrace-log[fn]
stacktrace.clj:80 ring.middleware.stacktrace/wrap-stacktrace-web[fn]
jetty.clj:27 ring.adapter.jetty/proxy-handler[fn]
(Unknown Source) ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle
HandlerWrapper.java:127 org.eclipse.jetty.server.handler.HandlerWrapper.handle
Server.java:500 org.eclipse.jetty.server.Server.handle
HttpChannel.java:386 org.eclipse.jetty.server.HttpChannel.lambda$handle$1
HttpChannel.java:562 org.eclipse.jetty.server.HttpChannel.dispatch
HttpChannel.java:378 org.eclipse.jetty.server.HttpChannel.handle
HttpConnection.java:270 org.eclipse.jetty.server.HttpConnection.onFillable
AbstractConnection.java:311 org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded
FillInterest.java:103 org.eclipse.jetty.io.FillInterest.fillable
ChannelEndPoint.java:117 org.eclipse.jetty.io.ChannelEndPoint$2.run
EatWhatYouKill.java:336 org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask
EatWhatYouKill.java:313 org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce
EatWhatYouKill.java:171 org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce
EatWhatYouKill.java:135 org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce
QueuedThreadPool.java:806 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
QueuedThreadPool.java:938 org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run
(Unknown Source) java.lang.Thread.run
Your mistake is on this line:
(doseq [row output] ...
The error message
Don't know how to create ISeq from: mybank.core$output
gives the clue. The variable output is the function, not a sequence like doseq expects. You meant to call the output function, so you need to use parentheses to create a function call like:
(doseq [row (output)] ...
Update
You need to include an external library to convert between EDN data and a JSON string. My favorite way is my own library Tupelo Clojure. Use it like this:
(ns tst.demo.core
(:use tupelo.core tupelo.test))
(let [data [{:timestamp "2020-09-11 14:29:30", :lat 36.0, :long 36.0, :user "michav"}
{:timestamp "2020-09-11 14:31:47", :lat 36.0, :long 36.0, :user "michav"}]]
(println (edn->json data)))
with result:
[{"timestamp":"2020-09-11 14:29:30","lat":36.0,"long":36.0,"user":"michav"},
{"timestamp":"2020-09-11 14:31:47","lat":36.0,"long":36.0,"user":"michav"}]
You will need a line like this in your project.clj:
[tupelo "20.08.27"]
Please also see this template project for an easy way to get started. Enjoy!

How to read Clojure's spec :macro-syntax-check errors

I copied the following joy.gui.DynaFrame definition from "Joy of Closure" Chapter 12.2.1
(ns joy.gui
(:gen-class
:name joy.gui.DynaFrame
:extends javax.swing.JFrame
:implements [clojure.lang.IMeta]
:prefix df-
:state state
:init init
:constructors {[String] [String]
[] [String]}
:methods [[display [java.awt.Container] void]
^{:static true} [version [] String]]
)
(:import (javax.swing JFrame JPanel JComponent)
(java.awt BorderLayout Container)))
Unfortunately, the syntax for :prefix has apparently changed since 2014, so the line 6 should read :prefix "df-".
Evaluating the incorrect code above I got the following error message:
2. Unhandled clojure.lang.Compiler$CompilerException
Error compiling src/dipping_feet/gui.clj at (1:1)
#:clojure.error{:phase :macro-syntax-check,
:line 1,
:column 1,
:source
1. Caused by clojure.lang.ExceptionInfo
Call to clojure.core/ns did not conform to spec.
#:clojure.spec.alpha{:problems
[{:path [],
:reason "Extra input",
:pred
(clojure.spec.alpha/cat
:docstring
(clojure.spec.alpha/? clojure.core/string?)
:attr-map
(clojure.spec.alpha/? clojure.core/map?)
:ns-clauses
:clojure.core.specs.alpha/ns-clauses),
:val
((:gen-class
:name
joy.gui.DynaFrame
:extends
javax.swing.JFrame
:implements
[clojure.lang.IMeta]
:prefix
df-
:state
state
:init
init
:constructors
{[String] [String], [] [String]}
:methods
[[display [java.awt.Container] void]
[version [] String]])
(:import
(javax.swing JFrame JPanel JComponent)
(java.awt BorderLayout Container))),
:via [:clojure.core.specs.alpha/ns-form],
:in [1]}],
:spec
#object[clojure.spec.alpha$regex_spec_impl$reify__2509 0x3b982314 "clojure.spec.alpha$regex_spec_impl$reify__2509#3b982314"],
:value
(joy.gui
(:gen-class
:name
joy.gui.DynaFrame
:extends
javax.swing.JFrame
:implements
[clojure.lang.IMeta]
:prefix
df-
:state
state
:init
init
:constructors
{[String] [String], [] [String]}
:methods
[[display [java.awt.Container] void]
[version [] String]])
(:import
(javax.swing JFrame JPanel JComponent)
(java.awt BorderLayout Container))),
:args
(joy.gui
(:gen-class
:name
joy.gui.DynaFrame
:extends
javax.swing.JFrame
:implements
[clojure.lang.IMeta]
:prefix
df-
:state
state
:init
init
:constructors
{[String] [String], [] [String]}
:methods
[[display [java.awt.Container] void]
[version [] String]])
(:import
(javax.swing JFrame JPanel JComponent)
(java.awt BorderLayout Container)))}
I omit the stack trace here.
My question is: is there a reference in the error message somewhere which would point me to the exact location of the error in the code? I had to basically guess which part of my definition is incorrect.
Yes, I agree, this is a confusing error message. This appears to be a bug in spec, so unfortunately I don't think there is anything you can do at this time to make the error any better.
https://clojure.atlassian.net/browse/CLJ-2013?oldIssueView=true

Why does the validation fail (ExceptionInfo Value does not match schema) for a prismatic schema using onyx?

Can someone throw light on whats going on here ? I have double checked dynamodb-local behavior using a non-onyxian client and simple operations work using Faraday . The code which I am trying to run is here and I have logged an issue here but haven't got any response.
Here is the output from the REPL:
$ lein repl
WARNING: cat already refers to: #'clojure.core/cat in namespace: clj-uuid.bitmop, being replaced by: #'clojure.core.reducers/cat
nREPL server started on port 44195 on host 127.0.0.1 - nrepl://127.0.0.1:44195
REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.7.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_25-b18
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
cqrs-server.core=> (start)
ExceptionInfo Value does not match schema: {:onyx/consumption missing-required-key, :onyx/batch-size missing-required-key, :onyx/medium missing-required-key} schema.core/validate (core.clj:161)
cqrs-server.core=>
The full stacktrace using *e is below:-
cqrs-server.core=> *e
#error {
:cause "Value does not match schema: {:onyx/consumption missing-required-key, :onyx/batch-size missing-
required-key, :onyx/medium missing-required-key}"
:data {:type :schema.core/error, :schema (conditional #object[onyx.validation$fn__16409 0x6ba7a7e4 "ony
x.validation$fn__16409#6ba7a7e4"] {:onyx/name Keyword, :onyx/type (enum :output :function :input), :onyx
/consumption (enum :concurrent :sequential), :onyx/batch-size (pred pos?), Keyword Any, :onyx/medium Key
word} #object[clojure.core$constantly$fn__4383 0x5a6f89f1 "clojure.core$constantly$fn__4383#5a6f89f1"] {
:onyx/name Keyword, :onyx/type (enum :output :function :input), :onyx/consumption (enum :concurrent :seq
uential), :onyx/batch-size (pred pos?), Keyword Any, :onyx/fn Keyword}), :value {:onyx/name :event/aggre
gate-out, :onyx/type :output}, :error {:onyx/consumption missing-required-key, :onyx/batch-size missing-
required-key, :onyx/medium missing-required-key}}
:via
[{:type clojure.lang.ExceptionInfo
:message "Value does not match schema: {:onyx/consumption missing-required-key, :onyx/batch-size miss
ing-required-key, :onyx/medium missing-required-key}"
:data {:type :schema.core/error, :schema (conditional #object[onyx.validation$fn__16409 0x6ba7a7e4 "o
nyx.validation$fn__16409#6ba7a7e4"] {:onyx/name Keyword, :onyx/type (enum :output :function :input), :on
yx/consumption (enum :concurrent :sequential), :onyx/batch-size (pred pos?), Keyword Any, :onyx/medium K
eyword} #object[clojure.core$constantly$fn__4383 0x5a6f89f1 "clojure.core$constantly$fn__4383#5a6f89f1"]
{:onyx/name Keyword, :onyx/type (enum :output :function :input), :onyx/consumption (enum :concurrent :s
equential), :onyx/batch-size (pred pos?), Keyword Any, :onyx/fn Keyword}), :value {:onyx/name :event/agg
regate-out, :onyx/type :output}, :error {:onyx/consumption missing-required-key, :onyx/batch-size missin
g-required-key, :onyx/medium missing-required-key}}
:at [schema.core$validate invoke "core.clj" 161]}]
:trace
[[schema.core$validate invoke "core.clj" 161]
[onyx.validation$validate_catalog invoke "validation.clj" 48]
[onyx.validation$validate_job invoke "validation.clj" 122]
[onyx.api$submit_job invoke "api.clj" 90]
[cqrs_server.core$start invoke "core.clj" 207]
[cqrs_server.core$eval19231 invoke "form-init17061160983479843.clj" 1]
[clojure.lang.Compiler eval "Compiler.java" 6782]
[clojure.lang.Compiler eval "Compiler.java" 6745]
[clojure.core$eval invoke "core.clj" 3081]
[clojure.main$repl$read_eval_print__7099$fn__7102 invoke "main.clj" 240]
[clojure.main$repl$read_eval_print__7099 invoke "main.clj" 240]
[clojure.main$repl$fn__7108 invoke "main.clj" 258]
[clojure.main$repl doInvoke "main.clj" 258]
[clojure.lang.RestFn invoke "RestFn.java" 1523]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__18624 invoke "interruptible_eval.clj"
87]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invoke "core.clj" 630]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1868]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 85]
[clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__18669$fn__18672 invoke "inte
rruptible_eval.clj" 222]
[clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__18664 invoke "interruptible_eval.clj"
190]
[clojure.lang.AFn run "AFn.java" 22]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1142]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 617]
[java.lang.Thread run "Thread.java" 745]]}
cqrs-server.core=>
cqrs-server.core=>
The output from a Faraday client REPL (my-ns is a local namespace for testing) which will connect to the same dynamodb running locally is below:
my-ns=> (far/list-tables client-opts)
(:events)
my-ns=> (far/describe-table client-opts :events)
{:lsindexes nil, :gsindexes [{:name :event-idx, :size 0, :item-count 0, :key-schema [{:name :type, :type :hash} {:name :date, :type :range}], :projection {:projection-type "ALL", :non-key-attributes nil}, :throughput {:read 1, :write 1, :last-decrease nil, :last-increase nil, :num-decreases-today nil}}], :name :events, :throughput {:read 1, :write 1, :last-decrease #inst "1970-01-01T00:00:00.000-00:00", :last-increase #inst "1970-01-01T00:00:00.000-00:00", :num-decreases-today 0}, :prim-keys {:id {:key-type :hash, :data-type :s}, :date {:key-type :range, :data-type :n}, :type {:data-type :s}}, :size 0, :status :active, :item-count 0, :creation-date #inst "2016-03-10T22:53:33.601-00:00", :indexes nil}
my-ns=>
my-ns=> (far/scan client-opts :events)
[]
I have created a public gist for core.clj here and for cqrs.clj here for review.
My project.clj looks like this.
Can someone please help me fix this ?
TIA
Based on the info you provided and our chat the answer straight to your question is that the last entry in the :catalog vector from the configuration is missing keys as indicated by the schema validation error:
{:onyx/consumption missing-required-key, :onyx/batch-size missing-required-key, :onyx/medium missing-required-key}
The offending entry (last one in the vector) is:
{:onyx/name :event/aggregate-out, :onyx/type :output}
And you need to fix it so it contains those missing keys:
{:onyx/name :event/aggregate-out,
:onyx/type :output,
:onyx/consumption <some value here>,
:onyx/batch-size <some value here>,
:onyx/medium <some value here>}
But in general I would rethink your general approach. What goal are you trying to achieve?
In my opinion it is not worth to struggle with getting to work a framework basing on a "randomly" selected old commit which seems to contain code in a broken state. How are you going to support your application if you discover a bug in cqrs-server? Will you fork it and support it yourself starting from that custom commit?
I would rather start with the requirements you have for your problem and then evaluate the solutions using more reliable and better supported library/framework so you have a better chance supporting your project.

How do I perform a Datomic transaction using the entity id of an enum / ref?

I'm attempting to insert a new entity into my Datomic database with references to enum / ref types that I've created (:client/gender and :client/referral).
The schema entry to the :client/referral type looks like this (and the :client/gender definition is almost identical):
{:db/id #db/id[:db.part/db]
:db/ident :client/referral
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/one
:db/doc "The referral source for this client"
:db.install/_attribute :db.part/db
}
[:db/add #db/id[:db.part/user] :db/ident :client.referral/friend]
[:db/add #db/id[:db.part/user] :db/ident :client.referral/online]
[:db/add #db/id[:db.part/user] :db/ident :client.referral/radio]
The transaction function looks something like this (I've tried all kinds of variations on it):
(defn add-client [client]
(let [gender (:gender client)
referral (:referral client)]
#(d/transact conn
[{:db/id (d/tempid :db.part/user)
:client/name (:name client)
:client/phone (:phone client)
:client/email (:email client)
:client/date-of-birth (:dateOfBirth client)
:client/gender gender
:client/referral referral}])))
This particular variation produces the following error:
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: :db.error/not-an-entity Unable to resolve entity: 17592186045422 in datom [#db/id[:db.part/user -1000022] :client/gender "17592186045422"]
...
Caused by: datomic.impl.Exceptions$IllegalArgumentExceptionInfo: :db.error/not-an-entity Unable to resolve entity: 17592186045422 in datom [#db/id[:db.part/user -1000022] :client/gender "17592186045422"]
error.clj:57 datomic.error/arg
error.clj:55 datomic.error/arg
db.clj:555 datomic.db/require-id
db.clj:2334 datomic.db/datomic.db.ProcessInpoint
db.clj:2317 datomic.db/datomic.db.ProcessInpoint
db.clj:2512 datomic.db/with-tx[fn]
PersistentVector.java:333 clojure.lang.PersistentVector.reduce
core.clj:6518 clojure.core/reduce
db.clj:2512 datomic.db/with-tx[fn]
db.clj:2516 datomic.db/with-tx
peer.clj:558 datomic.peer.LocalConnection/fn
peer.clj:558 datomic.peer/datomic.peer.LocalConnection
peer.clj:550 datomic.peer/datomic.peer.LocalConnection
api.clj:94 datomic.api/transact
...
I've also tried variations like this (among other things) but to no avail:
#(d/transact conn
[{:db/id (d/tempid :db.part/user)
:client/name (:name client)
:client/phone (:phone client)
:client/email (:email client)
:client/date-of-birth (:dateOfBirth client)
:client/gender #db/id[:db.user/part gender]
:client/referral #db/id[:db.user/part referral]}])
What, probably obvious, thing am I missing?
Your input data is the error source. Observe the string in the value position of the datom reported in the exception thrown.
[#db/id[:db.part/user -1000022] :client/gender "17592186045422"]
It should be the entity ID of a gender entity or a keyword identifiying it via :db/ident.
Make sure your transaction reads something like this:
[:db/add (d/tempid :db.part/user) :client/gender :gender/male]
(Assuming that you have an entity with :db/ident :gender/male)
(Side note: Your avatar image, the Clojure logo, is copyrighted I believe)
I switched to using :db/ident for the reference types and it resolved the issue.
#(d/transact conn
[{:db/id (d/tempid :db.part/user)
:client/name (:name client)
:client/phone (:phone client)
:client/email (:email client)
:client/date-of-birth (:dateOfBirth client)
:client/gender {:db/ident (:gender client)}
:client/referral {:db/ident (:referral client)}}])