Fork me on GitHub
#datomic
<
2022-02-18
>
jasonjckn05:02:22

Hey, I’m trying to dockerize datomic pro and my setup works just fine merely with a dockerized transactor, i’ll expose ports <tel:4334-4336|4334-4336>, and if I start-up the console not inside a container it works great, e.g

bin/console -p 8080 x "datomic:" 
However a problem occurs if launch the console from within a container via docker-compose (also datomic peer, exact same error), for some reason it won’t connect to the transactor over the docker compose network I get the following error (datomic console)
ActiveMQNotConnectedException.... Cannot connect to server(s). Tried with all available servers.... 
Same exception with dockerized Peer transactor.properties
protocol=dev
host=0.0.0.0
port=4334
storage-access=remote
storage-admin-password=changeme
storage-datomic-password=changeme
license-key=XYZ
here’s the command I use in docker compose to launch the console
command: "-p 8080 xyz datomic:"
JDKv8, Datomic Pro 1.0.6344

jasonjckn18:02:12

nevermind, solved it.

Hüseyin Yavaş00:05:00

I got the same error. Can you explain how did you solve it?

jasonjckn00:05:37

this was so long ago i don’t remember, i’ll send a couple screenshots of code though

Hüseyin Yavaş00:05:32

That would be awesome. Thank you!

jasonjckn00:05:45

not sure what else to send really

jasonjckn00:05:36

oh probably dockerfile helps

jasonjckn00:05:12

that’s console dockerfile , if you want me more let me know what

jasonjckn00:05:27

the very last screenshot is entrypoint.sh

Hüseyin Yavaş00:05:07

Thank you! I'll check them out

onetom06:02:08

how can i write a datalog query which picks between 2 where clauses, based on the presence of a query argument? eg:

(d/q '[:find ?e :in $ ?a ?v :where [?e ?a ?v]] db-val :attr "val")
but when ?v is nil, i want all entities, which has :attr:
(d/q '[:find ?e :in $ ?a ?v :where [?e ?a _]] db-val :attr nil)
can i express this in a single query? i've tried this:
(d/qseq
    {:query '{:find  [?e]
              :in    [$ ?a ?v]
              :where [(or (and [(some? ?v)] [?e ?a ?v])
                          (and [(nil? ?v)] [?e ?a _]))]}
     :args  [db-val :attr val]})
but got this error:
Execution error (ExceptionInfo) at datomic.core.datalog/eval-rule$fn (datalog.clj:1537).
Unable to find data source: $__in__4 in: ($ attrs $__in__3 $__in__4)
i found an example of this error here: https://gist.github.com/stuartsierra/2429063 which shows how it's not allowed to pass in nil arguments to queries, but it doesn't suggest what to do instead.

onetom06:02:18

i figured using false for the value of val would work, except for :db.type/bool attributes:

{:query '{:find  [?e]
            :in    [$ ?a ?v]
            :where [(or (and [(= false ?v)] [?e ?a ?v])
                        (and [(not= false ?v)] [?e ?a _]))]}
   :args  [db-val :attr val]}
or some other sentinel value, eg ::any or the a symbol any`, but not sure what's a good sentinel value. i have the feeling that this should be doable in a lot simpler way...

kipz09:02:57

The error looks like it's related to the inputs - it can't find the database. Have you tried just :in $ ?a ?v instead?

kipz09:02:29

But then - I tend to use the list form. This works for me

kipz09:02:33

[:find ?e
 :in $ ?a ?v
 :where
 (or
  (and [(= false ?v)]
       [?e ?a ?v])
  (and [(not= false ?v)]
       [?e ?a _]))]

Søren Sjørup13:02:30

Thanks for posting this, I ran into the same problem with nil inputs today. I wonder what the reason to not allow it could be.

Joe Lane15:02:09

An alternative approach here is to dynamically construct the query. cond-> is your friend here.

onetom18:02:31

@U0CJ19XAM yeah, i used this article, which used cond->, as a basis for my experiments: https://grishaev.me/en/datomic-query/ but in my case, i not just accreting where clauses, but have an either-or situation.

onetom18:02:37

anyway, i've ended up branching outside of the query, since both query variants are trivially short.

(defn pull-by-attr
  "Pulls all entities, using the `selector`, which have an attribute described by
`attr-ref`, optionally being equal to `attr-val`.

Number of results are not limited by default (:limit -1).

 :selector / selector   the selector expression
 :a / attr-ref          attribute :db/id or :db/ident or even a lookup-ref
 :v / attr-val          optional value
 :debug?                just return the query map, without executing it

For a complete description of the selector syntax, see
.

Returns a sequence of maps.

The arity-2 version takes :selector, :a and :v in arg-map, which
also supports :timeout, :limit and :offset. See namespace doc."
  ([db arg-map]
   (let [{:keys [selector a v]} arg-map]
     (pull-by-attr db selector a v (dissoc arg-map :selector :a :v))))

  ([db selector attr-ref]
   (pull-by-attr db selector attr-ref nil))

  ([db selector attr-ref attr-val-or-opts]
   (if (map? attr-val-or-opts)          ;; an attr-val can't be a map ever
     (pull-by-attr db selector attr-ref nil attr-val-or-opts)
     (pull-by-attr db selector attr-ref attr-val-or-opts nil)))

  ([db selector attr-ref attr-val {:as query-opts :keys [debug? timeout limit offset]}]
   ((if debug?
      identity
      (comp (partial map first) d/qseq))
    (-> (if (nil? attr-val)
          {:query '[:find (pull ?e attrs) :in $ attrs ?a :where [?e ?a _]]
           :args  [db selector attr-ref]}
          {:query '[:find (pull ?e attrs) :in $ attrs ?a ?v :where [?e ?a ?v]]
           :args  [db selector attr-ref attr-val]})
        (assoc :limit -1)
        (merge (dissoc query-opts :debug?))))))

onetom18:02:13

i borrowed the docstring from the docstring of d/pull

onetom18:02:27

and here are some invocation examples:

(pull-by-attr db {:selector '[*]
                    :a        :some/attr
                    :v        "val"
                    :debug?   true
                    :limit    5})
  (pull-by-attr db '[*] :some/attr)
  (pull-by-attr db '[*] :some/attr {:debug? true})
  (pull-by-attr db '[*] :some/attr "val")
  (pull-by-attr db '[*] :some/attr "val" {:limit 5})

onetom18:02:16

and these are equivalent (i think):

(pull-by-attr db '[*] :some/attr nil)
  (pull-by-attr db '[*] :some/attr {:limit 5})
  (pull-by-attr db '[*] :some/attr nil {:limit 5})

onetom03:02:07

this could be implemented with d/index-pull too, but that would also return entities, where (< (:some/attr entity) "val"), so we would need to limit the results outside of the query engine (eg (take-while #(-> % :some/attr (= "val")))), so it's probably doing some extra work (because of chunking)