You started solo with the default SQLite store. Now a colleague is joining and you want shared state. This guide swaps the backend without touching application code.
Move a working SQLite-backed chachaml setup to a shared Postgres instance. Same API, same map shapes, same UI.
docker run -d --name pg -p 5432:5432 -e POSTGRES_PASSWORD=secret postgres:16-alpine.createdb chachaml or via SQL:
CREATE DATABASE chachaml;.:postgres alias in your deps.edn (already there in this
project).The :postgres alias bundles the JDBC driver + HikariCP connection
pool:
:postgres {:extra-deps {org.postgresql/postgresql {:mvn/version "42.7.4"}
com.zaxxer/HikariCP {:mvn/version "6.2.1"}}}
Start your REPL with the alias:
clj -A:postgres
(require '[chachaml.core :as ml]
'[chachaml.store :as store])
(ml/use-store!
(store/open {:type :postgres
:jdbc-url "jdbc:postgresql://localhost:5432/chachaml"
:username "chachaml"
:password "secret"}))
The schema is created automatically on first connect (idempotent).
(ml/with-run {:experiment "smoke-test"}
(ml/log-metric :hello 1.0))
(ml/last-run)
;; => {:id "..." :experiment "smoke-test" ...}
Open the UI against the same backend:
DB_TYPE=postgres \
JDBC_URL=jdbc:postgresql://localhost:5432/chachaml \
DB_USER=chachaml \
DB_PASSWORD=secret \
clojure -M:ui:postgres
Browse to http://localhost:8080/runs and you should see your test
run.
Schemas are compatible at the conceptual level but not at the SQL level — column names and types are tuned per backend. There's no built-in migrator. Two practical options:
Cut over and start fresh. For a small team, the simplest path is to keep both stores around for a week, then archive the SQLite file once everyone has migrated.
Replay through the API. If you need history, write a small script that reads runs from the SQLite store and re-logs them through the public API. Sketch:
(require '[chachaml.store.sqlite :as sqlite])
(def src (sqlite/open {:path "old.db"}))
(def dst (store/open {:type :postgres ...}))
(chachaml.core/with-store dst
(doseq [r (chachaml.core/with-store src (ml/runs {:limit 10000}))]
(ml/with-run (select-keys r [:experiment :name :tags])
(ml/log-params (:params r))
(doseq [m (:metrics r)]
(ml/log-metric (:key m) (:value m) (:step m))))))
Note: this re-creates runs with new ids and new timestamps; it's a replay, not a 1:1 mirror.
psql -h ... -U chachaml -d chachaml
works from the same machine. If you're running chachaml inside
Docker, localhost won't reach the host; use the service name or
host.docker.internal. See Troubleshooting.CREATE privileges on the
database. If you're using a least-privilege user, run the DDL once
as a superuser, then drop create privileges.docker compose up.my-runs filtering.Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |