Fork me on GitHub
#datomic
<
2023-05-17
>
Can08:05:41

Hello everyone, I started working with Datomic and I need to learn how relations work. Is there any youtube video tutorial or course exist that you can advise me on? mainly I need about relations. i.e. in an extremely basic shop app database, there are 3 items, how should I design stock schema, order schema, user schema, and db-schema? and how should I build relations between schemas? Mainly I need the learn such things. Thank you so much πŸ™‚

igrishaev08:05:22

I believe the schema design in Datomic is pretty similar to Postgres. Design the users, orders, stocks tables on paper. These will be entities connected with foreign keys. Then transfer it to Datomic. The only difference is the foreign keys become refs.

Can08:05:50

(def db-schema
  [{:db/ident       :product/id
    :db/valueType   :db.type/long
    :db/unique      :db.unique/identity
    :db/cardinality :db.cardinality/one}
   {:db/ident       :product/label
    :db/valueType   :db.type/string
    :db/unique      :db.unique/identity
    :db/cardinality :db.cardinality/one}
   {:db/ident       :product/type
    :db/valueType   :db.type/string
    :db/cardinality :db.cardinality/one}
   {:db/ident       :product/model-no
    :db/valueType   :db.type/string
    :db/cardinality :db.cardinality/one}])
(d/transact conn {:tx-data db-schema})

(def stock-schema
  [{:db/ident       :stock/product
    :db/valueType   :db.type/ref
    :db/cardinality :db.cardinality/one}
   {:db/ident       :stock/amount
    :db/valueType   :db.type/long
    :db/cardinality :db.cardinality/one}])
(d/transact conn {:tx-data stock-schema})

(def order-schema
  [{:db/ident       :order/product
    :db/valueType   :db.type/ref
    :db/cardinality :db.cardinality/one}
   {:db/ident       :order/user
    :db/valueType   :db.type/ref
    :db/cardinality :db.cardinality/one}
   {:db/ident       :order/size
    :db/valueType   :db.type/long
    :db/cardinality :db.cardinality/one}])
(d/transact conn {:tx-data order-schema})

(def user-schema
  [{:db/ident       :user/id
    :db/valueType   :db.type/long
    :db/cardinality :db.cardinality/one}
   {:db/ident       :user/name
    :db/valueType   :db.type/string
    :db/cardinality :db.cardinality/one}
   {:db/ident       :user/password
    :db/valueType   :db.type/string
    :db/cardinality :db.cardinality/one}])
(d/transact conn {:tx-data user-schema})

(def product-data
  [{:product/id       100
    :product/label    "lacoste"
    :product/type     "urban clothing"
    :product/model-no "polo shirt"}
   {:product/id       101
    :product/label    "canada goose"
    :product/type     "jackets"
    :product/model-no "caban"}
   {:product/id       102
    :product/label    "mammut"
    :product/type     "boots"
    :product/model-no "hiking boots"}
   {:product/id       103
    :product/label    "husky"
    :product/type     "sleeping bags"
    :product/model-no "arnapurna"}])
(d/transact conn {:tx-data product-data})
(def db (d/db conn))                                        ;;refresh database

(def stock-data
  [{:stock/product (get-entity-id-by-label "lacoste")
    :stock/amount  10}
   {:stock/product (get-entity-id-by-label "canada goose")
    :stock/amount  8}
   {:stock/product (get-entity-id-by-label "mammut")
    :stock/amount  6}
   {:stock/product (get-entity-id-by-label "husky")
    :stock/amount  4}])
(d/transact conn {:tx-data stock-data})

Can08:05:14

Yes, As you can say I need to learn about refs. I tried to build an example db with relations. But I am not sure about my refs, reletions are built correctly. I saw some examples that generally puts refs into vectors which is a different attempt then what I tried. Some kind of things. πŸ™‚

igrishaev08:05:00

Just a note: your product has two unique fields: product/id and product/label. Du you really need both?

Can08:05:41

I think that's a mistake.

Can08:05:08

I guess I have to change it, isn't it?

igrishaev08:05:53

Usually a good has SKU or similar unique string. Once you're created an entity in Datomic, it obtains a unique id so there is no need to pass it explicitly

igrishaev08:05:05

so in your case, a unique string field product/sku would be fine. But it depends on your data, after all. If you import some legacy data from Postgres, you might need to track the old Postgres ID for rare cases.

Can09:05:08

Is this unique field help me to track that issues?

igrishaev09:05:21

well, I don't know. I just noticed that your product has two unique fields, and one of them is an integer which is a bit redundant.

Can09:05:32

Yes, thanks for sharing with me. That was a mistake I just fixed in my repo. πŸ™‚

Can07:05:29

Thanks πŸ™‚

Can19:05:14

@U9E8C7QRJ hello thats nice and fun. Where can I find solutions do you know?

Eduardo Lopes12:05:29

Following https://docs.datomic.com/cloud/schema/defining-schema.htmldid not work for me, tried the same code running (d/transact conn {:tx-data name-schema}) but it only worked with (d/transact conn name-schema). Why wouldn't work with :tx-data? Returned this to me:

Execution error (ClassCastException) at datomic.api/transact (api.clj:105).
class clojure.lang.PersistentArrayMap cannot be cast to class java.util.List (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.util.List is in module java.base of loader 'bootstrap')

favila13:05:40

Those docs are for cloud using the client api (datomic.client.api/transact). You are using on-prem peer api (datomic.api/transact), whose parameters are a different shape.

βœ… 2
favila13:05:46

> Execution error (ClassCastException) at datomic.api/transact (api.clj:105).

Eduardo Lopes13:05:18

Thanks, I didn't notice πŸ˜…

favila13:05:19

(Using the same β€œd/” namespace alias for the client api in official documentation was I think a really big mistake. I personally always use dc/_ to distinguish)

πŸ’‘ 2
Robert A. Randolph15:05:44

@U09R86PA4 Thanks for pointing out that subtle confusion with d/. We're working on some docs updates and have added that to the list of things to evaluate.

Eduardo Lopes13:05:05

I'm renaming an attribute from :file/path to :deprecated/file.path and it did not change on my Datomic Console, even when I run (d/attribute (d/db conn) :file/path) ir returns :ident :deprecated/file.path inside #AttrInfo. It is possible to get also on Datomic Console?

favila14:05:48

in implicit entity-id resolution contexts (e.g. d/entid, keyword lookup on an entity map, pull expressions, the attribute slot of a datalog clause), no-longer-asserted idents still resolve

favila14:05:04

this is by design, so you don’t have to change code and data in lockstep when renaming attributes

favila14:05:49

i.e. both :file/path and :deprecated/file.path will resolve to the same attribute

favila14:05:02

but [?attr :db/ident :file/path] in a datomic query will not

vncz20:05:48

Now that Datomic is free, does anybody know where to download com.datomic/dev-local without using the cognitec repository?

πŸ™Œ 2
Robert A. Randolph15:05:22

@U015VUATAVC For now it is still only available through the Cognitect repository. If you could share why you find this problematic, that may inform choices we make when improving how to get dev-local.

vncz15:05:28

The long story short is when circulating demos around people need to register and then modify their maven repository settings to put the token @UEFE6JWG4

βž• 6
vncz15:05:01

Assuming there is no license problems since now the platform is free, having it just on Mavens would make my life easier

Robert A. Randolph15:05:14

Right, makes sense. We hope to have something that will make this much easier for you after we've worked on some other follow up work (e.g. Cloud)

vncz15:05:32

Thank you!

Daniel Jomphe16:05:21

Yes, many teams mention the maven setup as an annoyance. Here on the DevOps side it even made us loose some days with a hard to understand issue happening only in the context of Docker-based github actions.

πŸ‘ 4
πŸ’― 2
abrooks22:05:38

A blog post would be great when dev-local distribution changes. This is something I'm very keen on and I'm sure others are as well.