Liking cljdoc? Tell your friends :D

pgmalli.core

Generate malli schemas from an applied PostgreSQL schema.

Config: {:schemas ["public"] ; default ["public"] :out-dir "resources/pgmalli" ; default; one file per schema, <out-dir>/<schema>.edn :overrides {constraint-name malli-schema | {:skip reason}} :db {:host :port :db :user :password :sslmode :psql}} ; optional; psql's environment otherwise

The config, the generated file layout and the fact vocabulary (see pgmalli.impl.pattern) are the stable contract. pgmalli.impl.* may change without notice.

Generate malli schemas from an applied PostgreSQL schema.

Config:
  {:schemas ["public"]           ; default ["public"]
   :out-dir "resources/pgmalli"  ; default; one file per schema, <out-dir>/<schema>.edn
   :overrides {constraint-name malli-schema | {:skip reason}}
   :db {:host :port :db :user :password :sslmode :psql}}  ; optional; psql's environment otherwise

The config, the generated file layout and the fact vocabulary (see pgmalli.impl.pattern)
are the stable contract. pgmalli.impl.* may change without notice.
raw docstring

pgmalli.impl.expr

Turns expressions as printed by PostgreSQL's deparser (pg_get_constraintdef, pg_get_expr) into HoneySQL-style data. Only that output format is supported, not arbitrary SQL.

Covered: comparison, logical and arithmetic operators; IS [NOT] NULL/TRUE/FALSE; IN; ANY/ALL (ARRAY[...]); BETWEEN; LIKE/ILIKE/~/~*; ::casts; function calls; TRIM(BOTH FROM x); CASE; CURRENT_TIMESTAMP and friends; AT TIME ZONE; (x).field; x[i]; quoted identifiers; string, number, boolean and NULL literals.

Operators whose symbol is not a readable EDN keyword (~, @>, ...) get a named keyword (see edn-safe-ops); ->honeysql maps them back when SQL has to be generated.

Turns expressions as printed by PostgreSQL's deparser (pg_get_constraintdef, pg_get_expr)
into HoneySQL-style data. Only that output format is supported, not arbitrary SQL.

Covered: comparison, logical and arithmetic operators; IS [NOT] NULL/TRUE/FALSE; IN;
ANY/ALL (ARRAY[...]); BETWEEN; LIKE/ILIKE/~/~*; ::casts; function calls; TRIM(BOTH FROM x);
CASE; CURRENT_TIMESTAMP and friends; AT TIME ZONE; (x).field; x[i]; quoted identifiers;
string, number, boolean and NULL literals.

Operators whose symbol is not a readable EDN keyword (~, @>, ...) get a named keyword
(see edn-safe-ops); ->honeysql maps them back when SQL has to be generated.
raw docstring

pgmalli.impl.generate

Config -> generated EDN files, one per schema.

Config: {:schemas ["public"] ; default ["public"] :out-dir "resources/pgmalli" ; default; files are <out-dir>/<schema>.edn :overrides {constraint-name schema-or-{:skip reason}} :db {:host :port :db :user :password :sslmode :psql}} ; optional; psql's environment otherwise

File contents: {:schema "public" :database-version "PostgreSQL 17.x ..." :registry {name schema} :unrendered [fact ...] :skipped [fact ...]}

Output is deterministic (sorted maps, pprint). Overrides that are not EDN (functions) are rejected at generation time.

Config -> generated EDN files, one per schema.

Config:
  {:schemas ["public"]           ; default ["public"]
   :out-dir "resources/pgmalli"  ; default; files are <out-dir>/<schema>.edn
   :overrides {constraint-name schema-or-{:skip reason}}
   :db {:host :port :db :user :password :sslmode :psql}}  ; optional; psql's environment otherwise

File contents:
  {:schema "public" :database-version "PostgreSQL 17.x ..."
   :registry {name schema} :unrendered [fact ...] :skipped [fact ...]}

Output is deterministic (sorted maps, pprint). Overrides that are not EDN (functions)
are rejected at generation time.
raw docstring

pgmalli.impl.ir

Reads the structure of one schema from pg_catalog through psql.

Connection settings are psql's own (PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE, ~/.pgpass); entries in the db map override them for the call.

Result shape: {:name "public" :database_version "PostgreSQL 17.x ..." :tables {"users" {:name "users" :columns [{:name :position :data_type :type_schema :is_nullable :default_value :generated_expr :identity :max_length :precision :scale}] :constraints {"users_age_check" {:name :type "CHECK" :check_clause :is_valid}}}} :types {"mood" {:kind "ENUM" :enum_values [...]} "email" {:kind "DOMAIN" :base_type :not_null :default :constraints [{:name :definition}]}}} Maps keyed by object name (:tables, :constraints, :types) keep string keys; everything else is keywordized. Expressions are the strings PostgreSQL's deparser produces.

Reads the structure of one schema from pg_catalog through psql.

Connection settings are psql's own (PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD,
PGSSLMODE, ~/.pgpass); entries in the db map override them for the call.

Result shape:
  {:name "public" :database_version "PostgreSQL 17.x ..."
   :tables {"users" {:name "users"
                     :columns [{:name :position :data_type :type_schema :is_nullable
                                :default_value :generated_expr :identity :max_length :precision :scale}]
                     :constraints {"users_age_check" {:name :type "CHECK" :check_clause :is_valid}}}}
   :types {"mood" {:kind "ENUM" :enum_values [...]}
           "email" {:kind "DOMAIN" :base_type :not_null :default :constraints [{:name :definition}]}}}
Maps keyed by object name (:tables, :constraints, :types) keep string keys; everything
else is keywordized. Expressions are the strings PostgreSQL's deparser produces.
raw docstring

pgmalli.impl.pattern

Facts about a schema, derived from the structure read by pgmalli.impl.ir.

A fact is a map with :fact (the kind), :schema, and :table / :column / :constraint where they apply. Column-local CHECK constraints are matched against a fixed set of patterns; anything else is kept as :table-check with the expression data, never dropped.

Kinds: :enum-type an enum type of the schema {:type-name :values} :column a column {:type :position :nullable? :default :identity? :generated} :enum column of an enum type {:type-name :values} :unknown-type type outside the mapping table {:type} :max-length varchar(n) {:max} :numeric numeric(p,s) {:precision :scale} :in-set col IN (...) / col = v {:values} :range col >= a AND col <= b, BETWEEN, ... {:min :max :min-exclusive? :max-exclusive?} :non-blank length(trim(col)) > 0 / col <> '' {:trim?} :length length(col) <= n / octet_length = n {:fn :min :max :exact} :json-type jsonb_typeof(col) = 'object' {:json-type} :regex col ~ 're' {:re :case-insensitive?} :not-null col IS NOT NULL :when-present col IS NULL OR <column pattern> {:fact-when-present} :table-check CHECK that matched no pattern {:expr :columns :valid?} :unparsed expression that could not be read {:input :error}

One CHECK can yield several facts (column patterns joined by AND). NOT VALID constraints are never matched, since existing rows may violate them.

Facts about a schema, derived from the structure read by pgmalli.impl.ir.

A fact is a map with :fact (the kind), :schema, and :table / :column / :constraint where they
apply. Column-local CHECK constraints are matched against a fixed set of patterns; anything
else is kept as :table-check with the expression data, never dropped.

Kinds:
  :enum-type    an enum type of the schema           {:type-name :values}
  :column       a column                              {:type :position :nullable? :default :identity? :generated}
  :enum         column of an enum type                {:type-name :values}
  :unknown-type type outside the mapping table       {:type}
  :max-length   varchar(n)                            {:max}
  :numeric      numeric(p,s)                          {:precision :scale}
  :in-set       col IN (...) / col = v                {:values}
  :range        col >= a AND col <= b, BETWEEN, ...   {:min :max :min-exclusive? :max-exclusive?}
  :non-blank    length(trim(col)) > 0 / col <> ''     {:trim?}
  :length       length(col) <= n / octet_length = n   {:fn :min :max :exact}
  :json-type    jsonb_typeof(col) = 'object'          {:json-type}
  :regex        col ~ 're'                            {:re :case-insensitive?}
  :not-null     col IS NOT NULL
  :when-present col IS NULL OR <column pattern>       {:fact-when-present}
  :table-check  CHECK that matched no pattern         {:expr :columns :valid?}
  :unparsed     expression that could not be read     {:input :error}

One CHECK can yield several facts (column patterns joined by AND). NOT VALID constraints
are never matched, since existing rows may violate them.
raw docstring

pgmalli.impl.render

Facts -> malli schemas. Every fact kind has exactly one rendering; there are no options.

registry returns {:registry {name schema} :unrendered [fact] :skipped [fact]}. Names: enum types as :pg.<schema>/<type>, tables as :pg.<schema>/<table>. A table schema describes one row as read from the database: every column present, nullable ones as [:maybe ...]. Column properties record provenance: :pg/type, :pg/default, :pg/constraint.

Identifiers that are not plain names (spaces, punctuation) become string keys so the result stays readable EDN.

overrides is {constraint-name schema-or-{:skip reason}}. A schema is added with [:and ...] to the column (column-local constraint) or the table (table constraint); :skip drops the fact from :unrendered into :skipped.

Facts -> malli schemas. Every fact kind has exactly one rendering; there are no options.

registry returns {:registry {name schema} :unrendered [fact] :skipped [fact]}.
Names: enum types as :pg.<schema>/<type>, tables as :pg.<schema>/<table>. A table schema
describes one row as read from the database: every column present, nullable ones as
[:maybe ...]. Column properties record provenance: :pg/type, :pg/default, :pg/constraint.

Identifiers that are not plain names (spaces, punctuation) become string keys so the
result stays readable EDN.

overrides is {constraint-name schema-or-{:skip reason}}. A schema is added with [:and ...]
to the column (column-local constraint) or the table (table constraint); :skip drops the
fact from :unrendered into :skipped.
raw docstring

pgmalli.main

Command line entry point. Config comes from pgmalli.edn in the working directory or the path given as second argument.

clojure -M -m pgmalli.main generate [pgmalli.edn] clojure -M -m pgmalli.main check [pgmalli.edn] ; exit 1 when files are stale bb -m pgmalli.main ...

Command line entry point. Config comes from pgmalli.edn in the working directory or
the path given as second argument.

  clojure -M -m pgmalli.main generate [pgmalli.edn]
  clojure -M -m pgmalli.main check    [pgmalli.edn]   ; exit 1 when files are stale
  bb -m pgmalli.main ...
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close