Getting Started with Datomic and PostgresSQL

Datomic is an immutable database created by Cognitect. For more read this: https://docs.datomic.com/on-prem/getting-started/brief-overview.html

Overview

  1. Installation

  2. Storage Service

  3. Datomic

  4. Usage Options

  5. Datomic Console UI

1. Installation

Create a project

> lein new datomic_postgres_example

Download Datomic-Pro Edition

Go to this website below and sign up and download Datomic pro.

Install Datomic

Once you have downloaded Datomic pro, next step is to install Datomic to your local maven repo. cd into the folder and run this script.

> bin/maven-install

This will install Datomic in your local maven repo. Once this is done we can use datomic from leiningen

Next, in your project, add the following to the dependencies section of your project.clj:

;; Add this in project.clj
[com.datomic/datomic-pro "0.9.6014"]

2. Storage Service

Set up Storage Service

Next step is to set up storage service. In our example we will set up postgresl storage service.

Set up Storage Service - Install dependencies

Datomic depends on various storage client libraries. You can find the recommended versions of all storage client libraries in the `provided` scope of the Datomic pom.xml file:

Dependencies can be installed from within the datomic folder using the script below

mvn dependency:list -DincludeScope=provided

Once the dependencies has been installed, we can move to the next step and provision a SQL database

Provisioning a SQL database

The steps to provision a SQL database as your Storage Service are:

  • setup a SQL database, or use an existing one

  • create SQL table (datomic_kvs)

  • create SQL user(s), or use an existing one

  • get jdbc connection string

  • Add JDBC driver dependencies to your project

  • install license key

There are scripts for doing each of the first three steps with PostgreSQL,  in the Datomic distribution's bin/sql directory. You can run them using their respective command line or GUI admin tools.

For example, for Postgres at the command line:

psql -f bin/sql/postgres-db.sql -U postgres
psql -f bin/sql/postgres-table.sql -U postgres -d datomic
psql -f bin/sql/postgres-user.sql -U postgres -d datomic
Clojure

The last script creates a user named 'datomic' with the password 'datomic'. You can use an existing user instead, or modify the script to create a user with a different username or password, if desired.

If you want to use a different SQL server, you'll need to mimic the table and schema from one of the included databases.

Adding JDBC driver in your project

In a leiningen project, add the following to the dependencies section of your project.clj:

;; in collection under :dependencies key
[org.postgresql/postgresql "9.3-1102-jdbc41"]
Clojure

Now you are ready to install your license key.

3. Datomic

Install your licence key

To use a storage other than free, you will need to use a Pro license. If you do not have a license yet, you can request a Starter License.

Next copy config/samples/sql-transactor-template.properties somewhere locally and edit it with the text editor of your choice. Paste in the license key from the email sent to you via My Datomic: NOTE: The license key is only provided via email and is not the same as the download key shown on the my.datomic.com Dashboard.

Once you have your key, you can install it by pasting the key into the value of the license-key property in your transactor properties file:

license-key=XXXXXXXX...
Clojure

You are now ready to start the transactor.

Run Local Transactor

A Datomic transactor performs ACID transactions for a set of databases.

Once your Storage Service is configured, you can start the Transactor locally by running bin/transactor. It takes a properties file as input. The file varies depending on the Storage Service:

To start the Transactor, run the following command, passing in your properties file:

bin/transactor datomic_properties/sql-transactor-template.properties
Clojure

This script will print a few lines of output, including the base URI you will use to connect, e.g.

datomic:sql://<DB-NAME>?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic
Clojure

To create a connection string, simply replace <DB-NAME> with a database name of your choice, e.g. "hello":

datomic:sql://hello?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic
Clojure

Creating a database

In a leiningen project, add the following to the dependencies section of your project.clj:

;; in collection under :dependencies key
[com.datomic/datomic-pro "0.9.6014"]
Clojure

Once done, fire up the Clojure REPL

lein repl
Clojure

Now go to your core name space and add the following code

(ns datomic-example.core
  (:require [datomic.api :as d]))
;; ====================== Database ==========================
;; Creating and Deleting database
; (def db-uri "datomic:dev://localhost:4334/hello")
(def db-uri "datomic:sql://hello?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic")
;; Create Database
(d/create-database db-uri)
Clojure

Once you've created the database, you can interact with it via the Datomic Peer or Client Libraries.

4. Usage Options

Option A: Using Peer Library

Once you have created a database, you can use the Datomic Peer Library to interact with it.

In the same file you used to create your database run:

;; Create a connection
(def conn (d/connect db-uri))
Clojure

Doing this will connect you to the transactor. Any transactions submitted to the connection will be persisted to your local file system.

For Example

(def dog-schema  [{:db/ident :dog/name
                   :db/valueType :db.type/string
                   :db/cardinality :db.cardinality/one
                   :db/unique :db.unique/identity
                   :db/doc "Name of the Dog"
                   :db.install/_attribute :db.part/db}
                  {:db/ident :dog/breed
                   :db/valueType :db.type/string
                   :db/cardinality :db.cardinality/one
                   :db/doc "Breed of the Dog"
                   :db.install/_attribute :db.part/db}
                  {:db/ident :dog/favorite-treat
                   :db/valueType :db.type/string
                   :db/cardinality :db.cardinality/one
                   :db/doc "Dog's Favorite Treat to Eat"
                   :db.install/_attribute :db.part/db}])
(d/transact conn dog-schema)
Clojure

Option B: Using Client Library

B. 1 - Starting a Peer Server

The Datomic Peer Server does not create durable-storage databases itself. To use a Peer Server along with a dev storage database you will need to have previously created a database and have a running dev Transactor. If you haven't yet created a database, follow the Create a database instructions prior to starting the Peer Server. If you haven't yet started a Transactor, follow the Run a Transactor instructions prior to starting the Peer Server.

The Datomic Peer Server provides an interface for Datomic clients to access databases. The Peer Server communicates with storage and the Transactor to service both reads from and writes to Datomic databases.

In a separate terminal instance run:

bin/run -m datomic.peer-server -h localhost -p 9004 -a myaccesskey,mysecret -d hello,datomic:sql://hello?jdbc:postgresql://localhost:5432/datomic?user=datomic&password=datomic
Bash in Clojure

Running this script will print the following lines of script

Serving datomic:sql://hello?jdbc:postgresql://localhost:5432/datomic?user=datomic as hello
Bash in Clojure

To start a Peer Server at localhost, port 9004 serving the hello database from dev storage as "hello" with the access key "myaccesskey" and the secret "mysecret".

More details on configuration and options can be found on the Peer Server documentation page.

B. 1 - Using Client Library

In a leiningen project, add the following to the dependencies section of your project.clj:

;; in collection under :dependencies key
[com.datomic/client-pro "0.9.41"]
Clojure

Next create a file called client.clj and require the client file

(ns datomic-example.pro-example.client
  (:require [datomic.client.api :as d]))
Clojure

Now, connect to the database by calling connect, the access-key/secret pair must match with one used to launch the Peer Server:

(ns datomic-example.pro-example.client
  (:require [datomic.client.api :as d]))
;; Configuration
(def cfg {:server-type :peer-server
          :access-key "myaccesskey"
          :secret "mysecret"
          :endpoint "localhost:9004"
          :validate-hostnames false}) ;; See this: https://forum.datomic.com/t/ssl-handshake-error-when-connecting-to-peer-server-locally/1067
;; Create a client
(def client (d/client cfg))
;; Create a connection
(def conn (d/connect client {:db-name "hello"}))
Clojure

Doing this will connect you to the transactor. To test the connection try to pull the data that you inserted earlier

;; Test to see if works
(d/pull (d/db conn) '[*] [:dog/name "Tiny"])
;; Outputs the following
{:dog/breed "Great Dane",
 :dog/name "Tiny",
 :db/id 17592186045423,
 :dog/favorite-treat "Cheese"}
Clojure

5. Console

Starting Datomic Console

The Datomic Console is a graphical UI that can be used to explore databases and generate queries.

Running Console against a dev storage-backed database requires a running Transactor. If you haven't yet started a transactor, follow the instructions at Running a local Transactor prior to starting Console.

In a separate terminal instance run:

bin/console -p 8084 localhost-postgres datomic:sql://?jdbc:postgresql://localhost:5432/datomic?user=datomic
Bash in Clojure

To start the Console web service on port 8084 against the local dev storage.

When the Console starts, it prints a URL to browse to, typically http://localhost:8084/browse/. Open this URL in a web browser to start using the Console.

The Console process can be terminated with Ctrl+C

More details on running and using Console can be found in the Datomic Console documentation page.

Runtimes (1)