Skip to content

Loading

There are two front doors for getting your Particles into a running server: load them at startup (--python-functions), or deploy them durably over the wire (particledb particles deploy). Both run the same collector, so the SQL signatures are identical wherever they are produced.

Pass --python-functions when starting the server. Each @scalar / @aggregate / @window-decorated function in the target is discovered, its signature built from the type hints, and it is registered so it is callable from SQL. The flag is repeatable and accepts a file, a package directory, or a dotted module name:

Terminal window
# A single module file
particledb start --python-functions ./particles/text.py
# A whole package directory (every *.py, non-underscore, is scanned)
particledb start --python-functions ./particles
# A dotted module name (must be importable)
particledb start --python-functions geo.distance
# Repeatable — combine several sources
particledb start \
--python-functions ./particles \
--python-functions geo.distance

After startup the discovered functions resolve directly from SQL — nothing else to run:

SELECT domain_of('kyle@jepsen.io'); -- 'jepsen.io'
SELECT slugify('Hello, World!'); -- 'hello-world'

Startup-loaded Particles go through the same internal registry as a durable deploy, and are audited as the system principal.

Verify locally — particledb particles verify

Section titled “Verify locally — particledb particles verify”

verify runs the discovery + signature stages locally and prints what it found. It makes no server call — use it to sanity-check a module before deploying:

Terminal window
particledb particles verify ./particles
discovered 1 module(s), 2 particle(s)
domain_of(text) -> text [scalar, immutable, strict]
slugify(text) -> text [scalar, immutable, strict]

Add --json for the full machine-readable manifest (useful in CI):

Terminal window
particledb particles verify ./particles --json

If a function is missing a type hint or uses an unsupported one, verify fails with a plain, source-located message — you fix your module, not the database.

Deploy durably — particledb particles deploy

Section titled “Deploy durably — particledb particles deploy”

deploy discovers your Particles and binds each one durably in a running server. It connects over the PostgreSQL wire control channel and persists each binding on the crash-atomic DDL/WAL path — so it survives a restart without re-passing --python-functions.

Terminal window
# Deploy to a local server (default target 127.0.0.1:5432)
particledb particles deploy ./particles
# Explicit target, namespace, and version
particledb particles deploy ./particles \
--namespace public \
--version 1 \
--target db.internal:5432

Common flags:

FlagMeaning
--target host:portServer to deploy to (default 127.0.0.1:5432).
--namespace <name>Catalog schema to bind into (default: server default, typically public).
--version <v>Explicit binding version (omit → server auto-assigns).
--dry-runRun discover + signature build, print the exact bindings, make no server call.
--jsonMachine-readable output for CI.
--no-signSkip signing (default for a dev server).

Connection defaults follow the standard PostgreSQL environment variables (PGUSER, PGDATABASE, PGPASSWORD); the user/database default to particledb.

A --dry-run shows exactly what would be bound without touching the server:

Terminal window
particledb particles deploy ./particles --dry-run
discovered 1 module(s), 2 particle(s)
domain_of(text) -> text [scalar, immutable, strict]
slugify(text) -> text [scalar, immutable, strict]
namespace: public
(dry-run) discovered + signatures built; no server call made.
would bind: domain_of(text) -> text [scalar]
would bind: slugify(text) -> text [scalar]