This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-27
Channels
- # announcements (2)
- # aws (31)
- # babashka (81)
- # beginners (82)
- # calva (38)
- # clj-kondo (41)
- # cljdoc (4)
- # cljs-dev (6)
- # clojure (101)
- # clojure-belgium (1)
- # clojure-europe (30)
- # clojure-germany (1)
- # clojure-italy (7)
- # clojure-nl (4)
- # clojure-norway (1)
- # clojure-spec (1)
- # clojure-uk (19)
- # clojurescript (16)
- # clojutre (1)
- # community-development (26)
- # core-logic (2)
- # data-science (26)
- # datomic (71)
- # events (3)
- # fulcro (55)
- # graalvm (2)
- # graphql (3)
- # joker (2)
- # kaocha (19)
- # luminus (2)
- # malli (6)
- # meander (3)
- # off-topic (6)
- # pathom (34)
- # random (1)
- # re-frame (2)
- # robots (1)
- # shadow-cljs (37)
- # sql (30)
- # tools-deps (21)
- # xtdb (4)
- # yada (25)
I have another newbie question about the map form for queries, regarding quoting as it feels like I have misunderstood something.
(d/query '{:query {:find [?e]
:in [$ ?title]
:where [[?e :title ?title]]}
:args [(d/db conn) "negroni"]})
gives me the error nth not supported on this type: Symbol
. When I quote the nested query map, it works (not surprisingly, as we don’t wanna eval all the datalog symbols that it complains about if i leave the whole thing unquoted). This works in the repl, but I don’t see how I would write code that does this to the query map without reaching for a bunch of map manipulation, the thought of which gives me that feeling that I’m doing something wrong.What confuses me is that in the docs, nothing is quoted. when querying with the map form.
https://docs.datomic.com/cloud/query/query-executing.html
It also shows the nested query map form for a /q and not /query invocation, which also confuses me, as i thought /q wanted a flat map and args as & args
, supplied directly to the function
I don't think you want to quote the args
, right?
(d/query {:query '{:find [?e]
:in [$ ?title]
:where [[?e :title ?title]]}
:args [(d/db conn) "negroni"]})
No, I guess not, but how do I only quote the query-map? This is the interface to the database, where parse-strainer
takes a map of user input and builds a query-map through a cond->
pipeline
(defn strain [strainer]
(let [query (parse-strainer strainer)]
(d/query query)))
The purpose of quoting is so symbols like ?e don’t get expanded to current.ns/?e
and lists like (some-rule)
in the query don’t get evaluated.
you can accomplish the same clause by clause, or using forms like (list 'some-rule '?foo ?bar)
or even (
'some-rule '?foo ~'?bar)`
yeah ok, that makes sense of course, I guess I don’t quote that much in Clojure otherwise.
But what I still don’t get is how they want to to use the api. If I have a fn that spits out the following map so that it might then be used to call d/query with, how do I quote only the :query
submap?
{:query {:find [?e]
:in [$ ?title]
:where [[?e :title ?title]]}
:args [(d/db conn) "negroni"]}
(update m :query quote)
evals the symbolsmy fn
(defn- parse-strainer [{:keys [:ingredients :search :type]}]
(cond-> base-query
ingredients (simple-query :ingredients '?ingredients ingredients)
type (simple-query :type '?type type)
search (fn-query :fulltext '?fulltext 'fulltext '$ search)))
(parse-strainer {:ingredients ["vodka" "cream"] :search ["russian"]})
{:query
{:find [(pull ?e [:id :title])],
:in [$ [?ingredients ...] [?fulltext ...]],
:where
[[?e :ingredients ?ingredients]
[(fulltext $ :fulltext ?fulltext) [[?e ?n]]]]},
:args [(d/db @*conn) ["vodka" "cream"] ["russian"]]}
but when i do (strain {:ingredients ["vodka" "cream"] :search ["russian"]})
i get
Execution error (UnsupportedOperationException) at datomic.datalog/extrel-coll$fn (datalog.clj:300).
nth not supported on this type: Symbol
I think it’s trying to use it as a vector-type datasource, but d/db doesn’t support nth
oh shoot, so i should somewhere do like (def db (d/db conn) and have :arg [db [“foo”] [“bar”]?
(defn strain [strainer]
(let [{:keys [query args]} (parse-strainer strainer)]
(apply d/q query (d/db @*conn) args)))
now works! before I hade a base map for my query that contained :args [(d/db @*conn)]
that i then conjed onto the other args tothe problem is that the db was literally a list, instead of the db object, so some quoting was going on that shouldn’t have.
i guess i just assumed that i would be invoked somewhere along the line, don’t think i’ve encountered this before
is there a best prefered way to pass the db argument around? in my cases, I’ve used (d/db @*conn)
where conn is an atom holding a (d/connect uri)
, would it be “better” if it was just a var with a (d/db conn)
?
https://docs.datomic.com/on-prem/best-practices.html#consistent-db-value-for-unit-of-work
also, it allows some priviledge scoping: anyone can transact with a conn, but not with a db
do you have any good open source reference projects that use datomic that one could look at?
Can I have one last quoting question? In my query, I want to pull and bind-coll with …
, which i can add to my q no problems,
{:query
{:find
[(pull ?e [:id :title :recipe :preparation :ingredients]) ...],
:in [$ [?ingredients ...] [?fulltext ...]],
:where
[[?e :ingredients ?ingredients]
[(fulltext $ :fulltext ?fulltext) [[?e ?n]]]]},
:args [#{"gin" "rum"} #{"russian"}]}
However, when I run this, it tells me that Argument ... in :find is not a variable
, despite that fact that it can handle the …
in the :in clauseDoes it have something to do with the fact the the other invocations of …
are nested? should not, right?
This is a peer vs client api difference. Only the former supports destructuring in :find
Hm, then that’s strange, I thought that Datomic free only used the peer api? It works in my hand written queries, which is what made me confused
Haha, no, I’m a free leecher for the moment. d/q takes args in map or vector form, d/query take maps with :query and :args keys, as Ive understood it. I have no clue about how the client api, have not researched that yet
Tried to use insecure HTTP repository without TLS:
project:
com/datomic/datomic-lucene-core/3.3.0/datomic-lucene-core-3.3.0.jar
This is almost certainly a mistake; for details see
I see that the datomic-pro-0.9-6024.pom contains
<repository>
<id>project</id>
<url></url>
I think they were fixing up some stuff like this recently iirc, but I'm not on the team
not sure if anyone is watching here atm
we’re hosting datomic-pro.jar in a private S3 repo. datomic-lucene-core also needs to be there. It wasn’t found in central
, so it tried all other repos, and then complained about the http://
ah, yes that is a common error reporting gotcha
if it looks in N places and doesn't find it, it just reports the first or last place it looked as it doesn't know where it was expected to find it
and often that is different than your expectation
For Datomic Ions, are there hooks for system (component, integrant, etc.) start/stop? Wondering about best practices here
In the past I’ve placed start
calls at the beginning of each HTTP request, right before handing the request to the app handler. Calls to start
are idempotent and are essentially no-ops if things are already started.
@UNRDXKBNY so it’s basically side-effecting middleware.
This gives you a well-defined place to assoc the started system onto the request map as well.
@cjsauer Yeah, I've basically done the same for system start
, though was a little worried about runtime performance and how much the no-op check would cost.
But are there any good solutions for stop
? Wondering about how to manage integrations like AWS API gateway and websockets, and having notifications on process cycling or auto-scaling
Hm, I haven’t needed stop
hooks myself. I wonder if you could tie into the Simple Workflow (SWF) hooks that Datomic sets up for coordinating deploys.
Ooh, didn't know about that part of Datomic (thanks for the pointer!), though it makes sense that something like SWF was behind coordinating deploys. I wonder if there's some buried api for this that wasn't too much trouble/not supported to hook into
@cjsauer Yeah, I've basically done the same for system start
, though was a little worried about runtime performance and how much the no-op check would cost.
But are there any good solutions for stop
? Wondering about how to manage integrations like AWS API gateway and websockets, and having notifications on process cycling or auto-scaling