Fork me on GitHub
#datomic
<
2017-05-11
>
james07:05:24

Does anyone know the best practice for naming booleans in Datomic? Is it possible to follow the Clojure practice of using “?” at the end, or are you using an “is-” pre-fix, or is some other approach preferred?

timgilbert21:05:09

james: I don't know if it's a best practice or not, but we've been using :user/disabled? and the like for boolean attributes and I like the way it looks. It also destructures nicely into local bindings named disabled? which seems like a plus: (let [{:keys [:user/disabled?]} query-result] ... (if disabled? foo bar))

james06:05:47

@U08QZ7Y5S Thanks for letting me know, and I like your approach.

tjtolton14:05:34

good question, I've always kind of wondered that.

bmaddy16:05:17

I have some related entities in datomic:

{:db/id 1
 :related
   ({:db/id 2 :name "B"})}
I’d like to do two different things to it. Replace the related entities (and retract the old ones):
{:db/id 1
 :related
   ({:db/id 3 :name "C"}
    {:db/id 4 :name "D"})}
and remove all related entities:
{:db/id 1
 :related ()} ;; yes, I'm aware this wouldn't technically exist anymore. I'm just printing it here to help describe what I'm looking for.
I tried replacing them like this:
(d/transact conn [{:db/id 1
                        :related updates}])
but that just appended new ones. What’s the best way to go about doing these in datomic? Do I really need to query the db again to find all the related items and retract them manually? If so, can I do that in a transaction somehow so that I can be sure another process doesn’t add another related entity at the same time?

favila16:05:50

Datomic only transacts changes (add/retract), not replacements (make the entity look like this). You have to emit retractions if you want to remove items

favila16:05:34

You can do this by query, compare, retract in the peer, but that is subject to race conditions (by the time transaction arrives at the txor, something else may have been added)

favila16:05:27

You can also use a db function like this: https://gist.github.com/favila/8ce31de4b2cb04cf202687c6a8fa4c94 (There are other ones out there which are a little smarter)

favila16:05:21

that eliminates the race since the work happens in the transactor. But you still need to think about who "wins" if different peers assert different things independently

favila16:05:47

e.g., do you really always want "last writer wins" semantics at entity+attribute granularity?

favila16:05:11

these are questions the app needs to answer for itself

favila16:05:20

Whatever policy you finally choose you can write transaction function interfaces to enforce them

bmaddy16:05:28

Are there any of these functions built in or do you always need to write them yourself? (a quick search yielded no results)

favila16:05:51

no, none are built-in

favila16:05:13

only :db.fn/cas and :db.fn/retractEntity are built-in

bmaddy16:05:41

Ok, thanks for the help--I appreciate it!

erichmond18:05:14

Sorry guys, one other question. I am trying to do a restore-db to a ddb-local instance, and the writes to the transactor are happening so fast I am losing the heartbeat. I am experimenting with the -Ddatomic.s3BackupConcurrency and -Ddatomic.backupPaceMsec system properties. Are these the right things to be tinkering with?

marshall18:05:14

restore doesn’t require a transactor

marshall18:05:19

(except for dev)

marshall18:05:38

the process running the restore writes directly to storage

val_waeselynck21:05:50

(disclaimer: I'm the author)

bmaddy21:05:29

@val_waeselynck Thanks--I’ll check that out!

timgilbert21:05:09

james: I don't know if it's a best practice or not, but we've been using :user/disabled? and the like for boolean attributes and I like the way it looks. It also destructures nicely into local bindings named disabled? which seems like a plus: (let [{:keys [:user/disabled?]} query-result] ... (if disabled? foo bar))