Fork me on GitHub
#datascript
<
2022-07-29
>
seepel09:07:36

I'm running into a bit of trouble with a unique constraint I've setup. I'm trying to update multiple entities in the same transaction, should the unique constraint be checked at each step of the transaction, or should it only check at the end? I'm trying to model a tree by using a schema that looks something like this

{:dom/parent {:db/valueType :db.type/ref
              :db/cardinality :db.cardinality/one}
 :dom/index {:db/cardinality :db.cardinality/one}
 :dom/parent+index {:db/valueType :db.type/tuple
                    :db/tupleAttrs [:dom/parent :dom/index]}}
I'm having trouble when trying to insert a node. I get an error about violating the :dom/parent+index constraint. My starting state looks like this
[{:db/id 4, :dom/id "84b84139-d507-45f2-baa1-29b6d727d978"}
 {:db/id 9,
  :dom/id "3952c3e6-4594-4c3d-9f79-ddba1b6233e5",
  :dom/index 0,
  :dom/parent #:db{:id 8}}
 {:db/id 12,
  :dom/id "ebcb660c-523a-46a7-a61a-00fdf1d3a96a",
  :dom/index 1,
  :dom/parent #:db{:id 4}}]
I'm basically incrementing the :dom/index attribute for both entities.
[{:db/id 4, :dom/id
  "84b84139-d507-45f2-baa1-29b6d727d978"}
 {:db/id 9,
  :dom/id "3952c3e6-4594-4c3d-9f79-ddba1b6233e5",
  :dom/index 1,
  :dom/parent 4}
 {:db/id 12,
  :dom/id "ebcb660c-523a-46a7-a61a-00fdf1d3a96a",
  :dom/index 2,
  :dom/parent 4}]
The error I'm getting indicates that I can't set entity 9's :dom/index because it exists on entity 12, but in the same transaction I am also changing entity 12's value to something else.
Cannot add #datascript/Datom [9 :dom/parent+index [4 1] 536870915 true] because of unique constraint: (#datascript/Datom [12 :dom/parent+index [4 1] 536870914 true])
Or is there something else I'm missing all together?

Niki10:07:26

I’m afraid constraints are checked each step of the transaction. So if you violate unique inside it’s no-go. That’s one of the differences from Datomic, and in your case it’s unfortunate. Maybe change the order in which attributes are updated?

seepel00:07:52

Thanks for being so responsive @U050UBKAA! 🙂 I did consider trying to organize the transactions but it's a bit difficult because I'm parsing the document from scratch each time. I'll probably punt and disable the unique check for now. I'm using prose mirror so there are a list of changes that I can parse, if end up going that route I should be able to order the transactions correctly.