This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-26
Channels
- # babashka (7)
- # beginners (85)
- # calva (39)
- # cider (3)
- # clara (1)
- # clj-kondo (10)
- # clojure (194)
- # clojure-europe (36)
- # clojure-madison (2)
- # clojure-nl (13)
- # clojure-spec (11)
- # clojure-uk (2)
- # clojurescript (17)
- # community-development (5)
- # component (9)
- # conjure (4)
- # core-async (3)
- # cursive (32)
- # data-science (26)
- # datomic (31)
- # graalvm (22)
- # holy-lambda (31)
- # honeysql (7)
- # introduce-yourself (1)
- # jobs (9)
- # jobs-rus (1)
- # lsp (3)
- # malli (9)
- # off-topic (54)
- # pathom (27)
- # pedestal (6)
- # portal (1)
- # re-frame (4)
- # releases (1)
- # remote-jobs (1)
- # sci (3)
- # shadow-cljs (4)
- # spacemacs (13)
- # vim (14)
- # xtdb (3)
Hello, I declared an ident as a 2-elements unique tuple as so:
{:db/ident :foo/uname+uid
:db/valueType :db.type/tuple
:db/tupleAttrs [:foo/uname :foo/uid]
:db/cardinality :db.cardinality/one
:db/unique :db.unique/identity}
Then, when I use it as a lookup ref in a pull call, it works:
(d/pull db '[*] [:foo/uname+uid ["domain" "123456"]])
But when I use it in a transaction:
@(d/transact conn
[{:db/id 987654321
:bar/link [:foo/uname+uid ["domain" "123456"]]}])
I get the following error:
...
1. Caused by datomic.impl.Exceptions$IllegalArgumentExceptionInfo
:db.error/not-a-keyword Cannot interpret as a keyword: domain, no leading :
{:cognitect.anomalies/category :cognitect.anomalies/incorrect,
:cognitect.anomalies/message
"Cannot interpret as a keyword: domain, no leading :",
:db/error :db.error/not-a-keyword}
...
Does someone understand the meaning and/or the reason of this error?
Thanks a lotDoes this work? [[:db/add 987654321 :bar/link [:foo/uname+uid ["domain" "123456"]]]]
. I suspect it’s just ambiguity in the map desugaring--it’s trying to interpret it as a list of entity refs instead of one large entity ref. That map->attribute stuff is not aware of what attributes mean.
Hello,
Yes it works. Thanks.
Nonetheless, it works with regular lookup refs, like [:foo/internal-name "plop"]
, it works well.
I tried to change the type of :foo/uname
from string to keyword, and now am getting the following error:
...
Caused by datomic.impl.Exceptions$IllegalArgumentExceptionInfo
:db.error/not-an-entity Unable to resolve entity: :domain
{:cognitect.anomalies/category :cognitect.anomalies/incorrect,
:cognitect.anomalies/message "Unable to resolve entity: :domain",
:entity :domain,
:db/error :db.error/not-an-entity}
It indeed seems to interpret the vector as a list of entities. But I don't understand why it does. Do you think that it is an inherent ambiguity coming from Datomic well defined semantics or a bug of misinterpretation ?The map syntax is syntax sugar and the syntax is inherently ambiguous. Also on-prem has this “auto-keywordization” feature where you can put a string where a keyword is expected (e.g. “:foo”) and it will coerce to a keyword. (This was added I think so using datomic from java is easier. Cloud doesn’t have it. It makes things worse here.) So what should {:foo [:bar ["box" "baz"]]}
mean? Is it [:db/add ID :foo :bar][:db/add ID foo [:box "baz"]]
? (the only possible interpretation before tuples were added.) Or is it [:db/add ID :foo [:bar ["box" "baz"]]
?
For backward compatibility, I think it has to be [:db/add ID :foo :bar][:db/add ID :foo [:box "baz"]]
And your puzzling stacktrace is because [:db/add ID :foo [:box "baz"]]
doesn’t make sense. It tried to turn the “domain” in ["domain" "123456"]
into a keyword via auto-keywordization and couldn’t.
But since idents have types, the [:db/add ID :foo :bar][:db/add ID foo [:box "baz"]]
case couldn't be possible since :foo would have a :db/valueType :db.type/keyword
type in the first assertion and a :db/valueType :db.type/ref
type in the second.
So the only valid case would be [:db/add ID :foo [:bar ["box" "baz"]]
after tuples introduction and error before, no ... ?
also, [:db/add ID :foo :bar][:db/add ID :foo [:box "baz"]]
is indeed possible if :foo is a ref
and in assertion contexts, so is -123
(temp id) or #db/id{:part :some-partition-kw :idx -1}
(a tempid record object)
Thanks a lot for all the information. I solved my problem with a little function:
(defn entity->attr-list [entity]
(let [id (or (:db/id entity)
(d/tempid :db.part/user))]
(->> (dissoc entity :db/id)
(mapv (fn [[key value]]
[:db/add id key value])))))
if you are really attached to the map syntax except for this one handling of tuple values, consider annotating the tuple ref with metadata and expanding only those map entries via a postwalk