This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-01-31
Channels
- # architecture (5)
- # beginners (35)
- # boot (150)
- # cider (1)
- # clara (7)
- # cljs-dev (131)
- # cljsrn (10)
- # clojure (76)
- # clojure-austin (3)
- # clojure-berlin (1)
- # clojure-brasil (1)
- # clojure-chicago (2)
- # clojure-dusseldorf (1)
- # clojure-italy (30)
- # clojure-nl (2)
- # clojure-russia (40)
- # clojure-serbia (2)
- # clojure-spec (25)
- # clojure-uk (13)
- # clojured (2)
- # clojurescript (106)
- # core-async (29)
- # datascript (65)
- # datomic (38)
- # emacs (8)
- # funcool (8)
- # hoplon (6)
- # jobs (3)
- # klipse (93)
- # luminus (16)
- # lumo (4)
- # off-topic (2)
- # om (11)
- # onyx (13)
- # pedestal (4)
- # protorepl (3)
- # re-frame (40)
- # reagent (31)
- # ring (6)
- # ring-swagger (4)
- # slack-help (5)
- # spacemacs (13)
- # untangled (17)
- # vim (2)
Alright little logistics issue here. Same thing as yesterday really I'm looking to insert one row, get the reference, and insert that reference into a second insert. But apparently when I insert the reference, something is expanding it? Wondering if it's in my code or what... I don't like pasting big code but here it is because I'm not sure where the issue is:
(defn insert! [data, type]
(let [inserts (into {:db/id -1}
(filter some? (map (fn [[k v]] [(keyword type (name k)) v]) data)))
result (d/transact! conn [inserts])]
(ffirst (:tx-data result))
))
(defn MESSAGE_CREATE [data]
(let [message (dissoc data :mentions :attachments :author :mention_roles :embeds)
user-ref (insert! (message :author) "user")]
(prn (str "Inserting reference " user-ref " as an author to the message " (message :id)))
(insert! (assoc message :author {:db/id user-ref}) "message")
))
Isn't that what I'm doing?
user-ref
returns the DB ID actually
And I cannot do this in one query - there might be many references in some of those inserts
I'm sure someone will come around ^_^
I'd rather not ping tonsky so I'll keep hacking at it in the meantime
Update: I've resolved that issue at least.
there might be issues with advanced compilations (and there certainly were at the start of the project), but we’ve been using DataScript ever since in both :none and :advanced without any problems
@eslachance proper way to extract ids from transact! results is to use
(let [res (d/transact! [{:db/id -1, :attr/... }])
tempids (:tempids res)
entity-id (get tempids -1)]
entity-id)
when you specify data for transact!, you use temprory ids (negative numbers). In the result it’ll return map with tempids, which maps your negative numbers to real database ids that were assigned during that transaction
that way even if you transact multiple entities in a single transaction, you can always figure out which was resolved to what
also (not sure if that’s relevant to your case or not), in a single transaction you can use same negative number multiple times (e.g. for specifying references from one entity to another) and it’ll be resolved to the same entity id
use of (ffirst (:tx-data result))
is not reliable, although it’ll work in current version
(d/transact! conn [{:db/id 1}])
(d/transact! conn [{:db/id 2, :author 1}]) ;; correct
(d/transact! conn [{:db/id 2, :author {:db/id 1}}]) ;; incorrect
ffirst didn't work on inserting data that did not result in the DB changing, so I switched it to this (my insert function):
(defn insert! [data, type]
(let [inserts (into {:db/id -1}
(filter some? (map (fn [[k v]] (if (some? v) [(keyword type (name k)) v])) data)))
result (d/transact! conn [inserts])]
(d/resolve-tempid conn (:tempids result) (d/tempid (keyword "db.part" type) -1))
))
Which works fine
Would (get (:tempids result) -1)
be better then? It's certainly more... clean and short 😄
Also I guess using 1
only works if the schema sets that field as a ref
which it is: :message/author {:db/type :db.type/ref}
Awesome! Thank you very much! I got this working in at least a basic manner, I'm super happy 😄
Is it normal that (ffirst (:tx-data result))
returned nil
if the transaction didn't change anything?
> Is it normal that (ffirst (:tx-data result))
returned nil
if the transaction didn't change anything?
yes. Tx-data only contains actual DB changes
Perfect.
> Also I guess using 1
only works if the schema sets that field as a ref
if you want references, you have to mark it in schema anyways
if you don’t, and you inserts something like :author {:db/id 1}
it’ll store an actual map
oh that's why it was expanding it, heh.
I have to admit when my friend @oahner was explaining datascript to me 2 days ago, it pretty much blew my mind. I'm hooked.
these things might sound counter-intuitive at first, but once you get it, it’ll all make sense
I've done some SQL, and I understand javascript Map() and references so it actually makes a lot of sense.
maybe a little bit non-traditional so that first encounter is not as smooth as other SQL storage
It's just a question of getting the syntax right and that's mostly because of my beginner's level with clojure
best way to understand it is to remember that under the hood everything is stored as tuples of [entity id, attribute, value, transaction id]
Actually my friend equated it more to nosql with a single table but arbitrary keys
> Actually my friend equated it more to nosql with a single table but arbitrary keys some similarities, yes
It just blows my mind that people are counting query times in nanoseconds in clojure 😄
It was a generalization really
although ahead-of-time schema is still needed (always for Datomic, for all non-trivial attributes in DataScript)
A bit of order in discord is great. Overall, I'm getting used to it pretty fast.
Now I just need to do the boring job of processing every packet coming from Discord, separating it into entities and inserting them as they come in.
I'm off to bed though, so thanks again and good night!
@tonsky here’s a stripped down version of my codebase with the pseudo-names problem: https://github.com/AdamFrey/datascript-pseudo-names-bug
I just recently started using datascript. I wanted to include the attrs in the find clause, but i get an error which i dont understand.
(query '[:find ?time ?attr ?type ?data
:where
[?e ?a]
[?a :db/attr ?attr]
[?e :type ?type]
[?e :data ?data]
[?e :time ?time]])
Error: Expected number or lookup ref for entity id, got :data
Any ideas on what im supposed to do differently?Actual a better question, would be how to do a group by in datascript. As thats why im trying to include the attr in the output.
@drewverlee If you want to group by without including the attributes in the resultset, look at the :with
clause: http://docs.datomic.com/query.html
I think the error comes from the first two where clauses, using ?a
in attribute position and then in entity position. I don't think attributes are entityids in datascript, like they are in datomic, they are simply keywords...
I’m seeing transactions come in to my d/listen!
listener in the wrong order when another listener commits a transaction. Here’s the output from both listeners printing (:tx-data tx-report)
"listener 1" [#datascript/Datom [0 :modal/open :new-outing t true]]
;; inside listener 1 - transacts [[:db/add 0 :modal/open :sign-up]]
"listener 1" [#datascript/Datom [0 :modal/open :new-outing t false] <#C07V8N22C|datascript>/Datom [0 :modal/open :sign-up t true]]
"listener 2" [#datascript/Datom [0 :modal/open :new-outing t false] <#C07V8N22C|datascript>/Datom [0 :modal/open :sign-up t true]]
"listener 2" [#datascript/Datom [0 :modal/open :new-outing t true]]