is there anything built in to flatten nested data, so when looking up refs in a pull query it returns the refs as sub hashmaps when i have a single key value can i flatten or should I do that afterwards ?
datomic has :xform
option in pull-api, but I don't think that has been ported to datascript. Even so, you would need to apply that to each ref individually. One way is to clojure.walk/postwalk
over the result and replacing all the known refs with their idents. You can either explicitly pass in the refs you need replaced or you can find all the refs automatically by querying the schema (or in the case of datascript - the initial schema map).
Fulcro RAD has some code that could serve as a good starting point (it considers both multiple and single cardinality): https://github.com/fulcrologic/fulcro-rad-datomic/blob/develop/src/main/com/fulcrologic/rad/database_adapters/datomic.clj#L80-L102
I prefer the postwalk approach, because it makes the conversion explicit and doesn't confuse data querying with data mangling 🙂
Woah, I joined this channel with the intent of asking this exact question..
I'm working with the learndatalog and kristianmandrup's tutorial at https://github.com/kristianmandrup/datascript-tutorial/blob/master/pull_data.md#pull-and-query-combined
The latter says I should be able to (d/pull-many db '[*] (d/q '[:find ?e :where [?e]]))
But there seem to be multiple things wrong with this: 1. You need to pass the db to the query function 2. The result of the query is a set of 1 element vectors that pull-many choke son
There's got to be something simple going wrong here?
This works, but seems like it should be unnecessary (d/pull-many @conn '[*] (flatten (vec (d/q '[:find ?e :where [?e]] @conn))))
1. Yes, you want to learn to pass an immutable db around to queries, not derefing an unkown state conn.
2. You're right about the set of tuples, but there is more sugar syntax: [:find ?e]
vs [:find ?e .]
vs [:find [?e ...]]
(what you're looking for)
3. Fetching all data like this seems like an unusual use-case; and if you want all eids, you can probably just take that straight out of the indices.
😮 I always assumed the ...
in examples was just the author eliding stuff that wasn't important, not that it was literal syntax.
agreed regarding #3, I'm just finding my way around datalog, and after putting stuff in a natural question is how do I get it all out?
thanks @pithyless your "domain modeling with datalog" talk got me here 🙂
thanks for that, not liking these nested replies I missed the replies till now 😕
but you have given me a few options to look into, think i need to make notes as I go and make a post about these things 🙂
ad 3. that's why it unusual - asking for "all" the data hardly ever comes up in practice; unless you want to serialize/backup/etc, and then it's probably more practical to use d/datoms
d/seek-datoms
d/history
etc.
currently I am making a query to grab data and make a csv files from the results
I ended up specifying each entity in the query instead of using pull inside d/q with the [*] wild card
@pithyless regarding #1, makes sense and is something I'm already used to when working with state maps, however is it possible to transact in datascript without involving the atom? that is I want a function to take db value, and return an updated db value. datacript's transact!
only operates on a connection.
@ramblurr have a look at d/with
and d/db-with
. Those both allow you to incorporate new datoms into a database as a pure function of db->db