Skip to content

02 schemas

Daniel Higginbotham edited this page Nov 2, 2022 · 6 revisions

datapotato is responsible for generating and inserting hierarchical data, but how does it know about the hierarchical relationships among your entities? If you’re building a forum, how does it know that a Post belongs to a User?

You configure these relationships with a potato schema:

(ns donut.datapotato-tutorial.02
  (:require [donut.datapotato.core :as sm]
            [loom.io :as lio]))

(def potato-schema
  {:user {:prefix :u}
   :post {:prefix    :p
          :relations {:owner-id [:user :id]}}})

(def potato-db
  {:schema potato-schema})

(defn ex-01
  []
  (sm/add-ents potato-db {:post [{:count 2}]}))

A potato schema is a map that defines ent types. datapotato uses ent types to create an ent graph when you call dc/add-ents, as in ex-01 above.

Defining ent types

In the schema, each key is the name of an ent type (:user and :post above) and each ent type’s definition is a map with the keys :prefix and (usually) :relations. These values are used to generate ent graphs.

What’s the :prefix key for? In generating the ent graph, each node needs to have a unique name, and :prefix is used to name ents. If you want to add three users with (dc/add-ents {:schema potato-schema} {:user [{:count 3}]}), the :user ent type’s :prefix of :u is used to generate ents named :u0 , :u1, and :u2. There’s a pattern here: every generated ent is named :{schema-prefix}{index}.

:relations defines how ents reference each other. The :post definition includes {:relations {:owner-id [:user :id]}}, specifying that a :post should reference a :user. The relation also specifies that the :post’s :owner-id should be set to the :user’s :id, information that will be used when generating records for these ents. (Covered in a later section).

These :relations are also what allow datapotato queries to be concise. If your query specifies that you want to create 3 :posts, you don’t also have to spell out that you need to create a user; datapotato can infer that.

(dc/add-ents {:schema schema} {:post [[2]]})

You don’t explicitly specify that a :user should be created, but datapotato knows to add one because the :post ent type’s :relations key specifies that :post~s reference a ~:user.

How ent types relate to your database tables

Ent types usually correspond to database tables. If you’re building a form that has posts and users, you’ll probably create a :post ent type and :user ent type. You can also define more than one ent type per database table; if you find yourself often testing authentication scenarios, for example, you could create an :invalid-user ent type and write code that would insert the data for those ents into your user table (how to do this will be clear by the end of the tutorial). Ent type names are not in any way magical, you should use whatever names are most convenient for you.

Clone this wiki locally