This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-08
Channels
- # admin-announcements (2)
- # beginners (35)
- # boot (353)
- # capetown (1)
- # cider (1)
- # cljs-dev (41)
- # cljsjs (3)
- # cljsrn (3)
- # clojure (118)
- # clojure-austin (12)
- # clojure-russia (17)
- # clojure-spec (21)
- # clojure-taiwan (1)
- # clojure-uk (91)
- # clojurescript (80)
- # clojurex (1)
- # cloverage (3)
- # datomic (66)
- # devcards (2)
- # events (2)
- # garden (6)
- # hoplon (54)
- # jobs-rus (1)
- # keechma (1)
- # lein-figwheel (4)
- # leiningen (3)
- # luminus (3)
- # off-topic (7)
- # om (4)
- # onyx (53)
- # other-languages (17)
- # proton (7)
- # protorepl (4)
- # re-frame (123)
- # reagent (1)
- # ring (6)
- # rum (2)
- # spacemacs (1)
- # specter (21)
- # testing (1)
- # untangled (1)
- # yada (42)
@pesterhazy, @robert-stuttaford, @podviaznikov: https://github.com/mrmcc3/tf_aws_datomic i’m sure there are many things that could be improved but I can at least confirm that this gives you a running transactor (with dynamo) and properly configured peers
thank you @mrmcc3 !
wow, awesome 🎁 @mrmcc3
indexing sorts datoms
sequential uuids sort faster
because most of the uniqueness is towards the end of the uuid value, which means that on average, it takes less bits of the uuid to determine a sort decision
that's my layperson understanding, anyway 🙂
I see. So there's no concept of a hash index that doesn't care about ranges, as in mongo?
datomic's indexes are like b-trees, if things are sequential it means the tree needs much less re-balancing
@yonatanel: semisequential guids are a good idea in general, you never know what kinds of indexes your data might want to live in
@yonatanel: adapting indexing (http://blog.datomic.com/2014/03/datomic-adaptive-indexing.html) means that Datomic will index efficiently even if store purely random values
it is a principle of Datomic that you should get good indexes by default, without having to make indexing choices up front (that inevitably serve some jobs well and other jobs poorly)
this is exactly the opposite of the “Model Around Your Queries” idea encouraged in e.g. Cassandra http://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling
Hi! I have a super-newbie question: After leiningen downloads the datomic peer library dependency correctly, when I (require ‘datomic.api) on my project, I get ClassNotFoundException clojure.lang.Tuple java.net.URLClassLoader.findClass (URLClassLoader.java:381). What’s happening? I’m stuck… thanks in advance!
@alexati: Alternatively it may be some other incompatible dep. You can run lein deps :tree
to find what may be conflicting
that has to be the Clojure dep
@stuarthalloway: Can I just use the squuid function when I need to generate an ID, even without datomic? e.g when I know I will need to store it later
yes, and the source code is like ~10 lines if you don’t want a dep
It is in the Clojure cookbook https://github.com/clojure-cookbook/clojure-cookbook/blob/master/01_primitive-data/1-24_uuids.asciidoc
btw, when there's partitioning involved, isn't it recommended to have the most significant part of the id all over the place, as is recommended with amazon s3 keys? (and of course ranges are not needed)
@yonatanel: depends on the partitioning scheme, but yes that can be a concern
hey guys just getting into using datomic, right now I am working on just a simple registered user system. testing the add and retract feature but I’ve notice I had to re-evaluate the db after each add/retract to see the effect take place. Am I missing something?
@severed-infinity: I imagine you are querying against the same database value. In Datomic the database is a value and database values are immutable. So whatever item you are adding and retracting has another value (new) that you need to use. Each transaction in Datomic adds a new database value and all of the old values are still present, but if you want the most recent value you will need to retrieve it first.
so I assume then what I’d want is some function (say add function) that gets the db in let binding?
For a much better and more detailed explanation: https://channel9.msdn.com/posts/Rich-Hickey-The-Database-as-a-Value
@severed-infinity: sure, that is one way of doing it.
@severed-infinity: There is also :db-after
you could use (without having to make another roundtrip): http://docs.datomic.com/clojure/index.html#datomic.api/transact
ah never thought of that, using that approach then would it be best to create the db as an atom?
@severed-infinity an atom holding the db value wouldn't give you persistence, so it's only useful for speculative work. Semantically a Connection is already a kind of reference holding db values
@val_waeselynck: ah okay, currently I am using the approach I mention earlier of using it in a
let
context but are there any good code examples or best practices code examples in regards to handling the db change over time?transacting and obtaining :db-after is the way to go, but you usually don't need to do it more than once
if you're adding several things, just make a batch transaction that adds them all at once
(def db (d/db conn))
…some transaction…
(set! db (:db-after transaction))
would this be the suggested approach?@severed-infinity: that's usually not necessary since Datomic stores the most recent transaction's :db-after
along with its connection, so all subsequent calls to (d/db conn) will return it.
(d/q '[:find ?e ?a ?v ?tx ?op
:in ?log ?tx
:where [(tx-data ?log ?tx)[[?e ?a ?v _ ?op]]]]
(d/log conn) <your-tx-id>)
@severed-infinity: The only time you ever need to access :db-after
directly is when you need to make sure you have a consistent view of the database, e.g. to avoid race conditions.
Hrm. Not sure how to code block on mobile. Anyway that query will get all the datoms for a given tx
Sure. And of course you can add clauses as normal to do whatever else you want. Remember to pass a db in addition to the log if you want to do any 'normal' querying additionally
@severed-infinity: you might want to look at Component (https://github.com/stuartsierra/component) for managing your db state throughout an application
In very general terms, functions that only query should take a db as an argument and functions that transact should take a connection
Also relevant: http://docs.datomic.com/best-practices.html#consistent-db-value-for-unit-of-work
@sdegutis: ah okay, its just that after adding a new user to the db and looking them up using the following query with id in this case representing an id in my system and db being the same as I declared above just simply returns an empty set unless I re-evaluate db before the call.
(d/q '[:find ?e :where [?e :user/id id]] db)
In actuality I use this function specially
(defn lookup-user [id]
(let [db (d/db conn)
result (d/q '[:find ?e
:in $ ?id
:where [?e :user/id ?id]] db id)]
result))
but that db bound in the let form still returns an empty upon querying
@severed-infinity: Right, like I said, if you want to see the value of your DB after your transaction, either use :db-after
or (d/db conn)
.
gotcha
Query for the datoms in the txn (as above), reverse the op position of all datoms in the txn (other than the txInstant one) and re-transact
Tim Ewald gave a really nice talk on Reified Transactions last year at conj: http://www.datomic.com/videos.html