Step DB (:db)
Quick Answer
Use flow/step :db with a required :database discriminator and a bound :connection.
Canonical backends are :postgres, :mysql, :clickhouse, :bigquery, and :firestore.
Canonical Shape
Common fields:
| Field | Type | Required | Notes |
|---|---|---|---|
:database | keyword/string | Yes | Backend discriminator |
:connection | keyword/string | Yes | Bound slot or connection id |
:max-results | int | No | SQL/BigQuery max rows (platform capped) |
:timeout | int | No | Query timeout seconds |
:persist | map | No | Persist large results as res:// refs |
Backend-specific fields:
| Backend | Required fields | Optional fields | Notes |
|---|---|---|---|
:postgres, :mysql, :clickhouse | :sql or :template | :params (vector), :timeout, :max-results | Positional params |
:bigquery | :sql or :template | :params (map), :dry-run, :timeout, :max-results | Named params (@param) |
:firestore | :collection | :where, :order-by, :limit | Collection query API (not SQL) |
Limits And Behavior
- SQL/BigQuery row cap: up to
5000rows (:max-results) - Firestore default
:limit:100, max1000 - Result payload budget:
1 MBper DB step result - For large/variable outputs, prefer
:persist
Connection Reuse Pattern
Define database requirements once in :requires, then reuse the slot in all DB steps:
{:requires [{:slot :warehouse
:type :database
:backends #{:postgres}
:label "Warehouse DB"}]
:functions [{:id :db-input
:language :clojure
:code "(fn [input] {:status (or (:status input) \"active\")})"}]
:flow
'(let [prepared (flow/step :function :prepare-db-input
{:ref :db-input
:input (flow/input)})]
(flow/step :db :query
{:database :postgres
:connection :warehouse
:sql "select id from users where status = ?"
:params [(:status prepared)]}))}
Use existing workspace connections before creating new ones:
breyta connections list --type database
breyta flows configure <slug> --set warehouse.conn=conn-...
Backend Auth And Binding Expectations
| Backend family | Recommended :requires | Connection expectation |
|---|---|---|
SQL (:postgres, :mysql, :clickhouse) | {:type :database :backends #{...}} | JDBC-style connection details stored in connection secret/config |
BigQuery (:bigquery) | {:type :database :backends #{:bigquery}} | GCP project + service-account auth in connection |
Firestore (:firestore) | {:type :database :backends #{:firestore}} | GCP project + service-account auth in connection |
Canonical Example (SQL + Template + Function)
{:templates [{:id :orders-since
:type :db-query
:sql "select id, amount, created_at from orders where created_at >= ? order by created_at desc"}]
:functions [{:id :orders-stats
:language :clojure
:code "(fn [rows] {:rows (count rows) :total-amount (reduce + 0 (map second rows))})"}]
:flow
'(let [rows (flow/step :db :fetch-orders
{:database :postgres
:connection :warehouse
:template :orders-since
:params ["2026-01-01"]
:max-results 1000})
stats (flow/step :function :summarize-orders
{:ref :orders-stats
:input rows})]
{:stats stats})}