Fork me on GitHub

I have the following schema:

{:db/ident :token/uuid
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/uuid
    :db/unique :db.unique/identity}
   {:db/ident :token/ordinal
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/long}
   {:db/ident :token/project
    :db/cardinality :db.cardinality/one
    :db/valueType :db.type/ref}
   {:db/ident :token/project+id
    :db/tupleAttrs [:token/project :token/id]
    :db/valueType :db.type/tuple
    :db/cardinality :db.cardinality/one
    :db/unique :db.unique/identity}
:token/ordinal is optional, and I'd like for the composite check :token/project+id to run only when :token/ordinal is not nil. Basically, I'd like like to make sure each token ordinal is unique per project, as long as it's set. Is that possible?

Jakub Holý (HolyJak)10:08:42

I know little about Datomic but I guess should allow you to do that, if there is nothing better


thanks, that's very helpful!

🎉 4
Jakub Holý (HolyJak)10:08:23

Question: In RDBMS, a cascading delete can have multiple levels: if table A depends on B that depends on C and I delete a row in C then the related rows in both B and A will be deleted. This can be modelled in Datomic with C being isComponent . But in RDBMS I can also only delete a row in B, which would then delete all its related rows in A. I suppose that is not possible in Datomic since, I guess, a subcomponent (B being a subc. of C) cannot be a component in its own right to its own subcomponents. Correct? Is there any good solution?


Datomic attrs are graph edges, so this example doesn’t map to the table model


IsComponent does two things:


For given [a :component-attr b], retractEntity a will also retractEntity b.


This is recursive, so you can retractEntity a chain of entities this way


Second thing: the reverse-relation in map projections will be cardinality-one.


@U0522TWDA :db/retractEntity is a transaction function You can re-implement :my.db/retractEntity with something like that

(defn my-custom-retract
  [db eid]
  (for [[e a v is-component] (d/q '[:find ?e ?a ?v ?is-component
                                    :in $ ?e
                                    [?a :db/ident]
                                    [?e ?a ?v]
                                    [(get-else $ ?a :db/isComponent false) ?is-component]]
                               db (d/entid eid))
        tx (cons [:db/retract e a v]
             (when is-component
               (my-custom-retract db v)))]

Once knowing it, you can do one of these: • create your specific retract-my-entity-a, that knows what to do when you retract a • create a generic :my-custom/is-component attribute and a custom my-custom-retract that implement retractions in the way that you expect.


PS: my-custom-retract will be a classpath function You can also use "database functions" But these database functions seems to be deprecated//not recommended.

Jakub Holý (HolyJak)12:08:37

Thanks a lot, both of you! > Datomic attrs are graph edges, so this example doesn’t map to the table model Aren't Foreign Keys in RDBMS also "graph edges"? > This is recursive, so you can retractEntity a chain of entities this way That is what I expected, when retracting the top-level entity C (i.e. a Conglomerate let's a company it owns go bankrupt, which removes all its departments and employees). What I was after is the ability to retract a thing deeper in the dependency tree and have all its subdependants have also retracted - e.g. we decide to cancel a department and fire all its employees. So I guess that, as @U2J4FRT2T suggests, I would need to add custom attributes to make this hierarchy of dependants (A -> B -> C) and a custom tx function that would automatically delete all relevant A entities when their parent B is deleted. I suppose I could use the card. one reverse relation to query for all the dependent entities and retract them manually.


> Aren’t Foreign Keys in RDBMS also “graph edges”?


I was speaking particularly to this sentence “if table A depends on B that depends on C”. Columns and foreign keys are defined on a table, it makes sense to say “table A depends on B”--it’s a graph edge, but it’s both “type” (table) and “instance” (row) level. But datomic attributes can be asserted on any entity and are stand-alone: they represent only the instance graph edge, not the subject or object entity. So it doesn’t make sense to speak this way, there’s no corresponding “table” in datomic.


You can make your own relation semantics as @U2J4FRT2T suggests, just like retractEntity does with isComponent. However I’ve found myself avoiding even isComponent because the deletion semantic is too baked-in and the “only one reference” semantic isn’t enforced strongly enough to be useful.


In sql, “delete” has a well-defined meaning (remove a row), so maybe the foreign key relations (cascading, aborting, etc) make sense.


in datomic, there is no “delete” in the same way. Entities are just IDs, you can’t “delete” them. the closest analog is “retract every asserted datom where the entity matches the E or V slot of the datom”, and that’s often not what I want. E.g., we have some attributes


common to many entity “types” which we don’t want deleted. Similarly, we don’t want transaction audit metadata to be retracted when the entity is retracted.

thinking-face 2
Tatiana Kondratevich15:08:24

Hi! Question about env-map and config settings. Can i store configuration like this in aws parameter store?

{:server-type :ion
     :region "<your AWS Region>" ;; e.g. us-east-1
     :system "<system name>"
     :endpoint "<your endpoint>"}
I want configure comfortable switching between dev and prod base. (on aws only prod and locally only dev). If I can't do this with parameter store how I can do this?


It really depends on how you manage your environments / profiles. The general goal is default to production, and override the parameters (in this case, the SSM key) locally. If you are using duct, there is a library for that purpose.

Joe Lane19:08:15

Hi @U028H6X0KRS , we support this scenario. See this blogpost with links to our docs. You can supply a different env-map per environment.