Fork me on GitHub
#datomic
<
2021-08-09
>
wei08:08:29

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 https://docs.datomic.com/on-prem/schema/schema.html#entity-predicates should allow you to do that, if there is nothing better

wei10:08:46

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?

favila11:08:58

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

favila12:08:14

IsComponent does two things:

favila12:08:59

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

favila12:08:38

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

favila12:08:50

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

souenzzo12:08:32

@U0522TWDA :db/retractEntity is a transaction function https://docs.datomic.com/cloud/transactions/transaction-functions.html#built-in 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
                                    :where
                                    [?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)))]

    tx))
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.

souenzzo12:08:18

PS: my-custom-retract will be a classpath function https://docs.datomic.com/cloud/transactions/transaction-functions.html#custom You can also use "database functions" But these database functions seems to be deprecated//not recommended. https://docs.datomic.com/on-prem/clojure/index.html#datomic.api/function

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.

favila13:08:00

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

favila13:08:10

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.

favila13:08:45

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.

favila13:08:41

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

favila13:08:12

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

favila13:08:17

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
Tatiana15: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?

hden14:08:39

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. https://github.com/hden/duct.module.datomic#usage

Joe Lane19:08:15

Hi @U028H6X0KRS , we support this scenario. See this blogpost with links to our docs. https://blog.datomic.com/2018/08/ion-parameters.html You can supply a different env-map per environment.