Skip to content
You're reading the docs for DRE 0.4 (v0.4.4). This page for 0.5 · New in 0.5

PostgreSQL

PostgreSQL: the postgres source, from the postgres package. Declare the package once in dependencies.yml; DRE installs it on demand:

dependencies.yml
plugins:
- postgres

Set in profiles.yml, under connections:, in a target with type: postgres.

Field Default Notes
host localhost Server host name.
port 5432 Server port.
user (required) User name.
password Password. Secret: use env_var().
database Database name.
dbname Libpq’s name for database
sslmode prefer Disable, prefer, require, verify-ca or verify-full. One of disable, prefer, require, verify-ca, verify-full.
sslrootcert CA certificate for verify-ca and verify-full. A file path; ~/ is your home directory.
schema Schema to put first on the search path.
role SET ROLE after connecting.
ssh Reach the server through an SSH bastion (a block of settings) Secret: use env_var().
connect_timeout 30s How long to wait for a connection (30s, 2m, or seconds) A duration (30s, 2m) or seconds.
retries 3 How many times to try again after a temporary error (0: never)
Field Notes
host, port Default localhost, 5432.
user, password
database (or dbname)
sslmode disable, prefer (default), require, verify-ca, verify-full, with libpq’s meanings.
sslrootcert CA certificate for verify-ca / verify-full. A leading ~/ is your home directory.
connect_timeout How long to wait for a connection: a duration (30s, 2m) or seconds. Default 30s (before 0.4, no limit). Queries themselves have no time limit; the run’s timeout is the backstop.
retries How many times to try connecting again after a temporary failure (the server unreachable, starting up, or dropping the connection). Default 3; a query is never tried again (see Tries again).
schema Put first on the search path.
role SET ROLE after connecting.
ssh Reach the server through an SSH bastion: a block of settings, below.

Capabilities: sessions, read_only, check (via EXPLAIN). numeric(p,s) becomes a decimal column. An unconstrained numeric becomes exact text, so cast it (::numeric(18,2)) when you want a typed column. Types DRE can’t map ask for a cast, e.g. interval_col::text.

Postgres drops numeric(p,s)’s precision and scale in VALUES lists and across UNION, so their numbers arrive as plain numeric, i.e. text. Cast in the outer query:

select code, amount::numeric(18,2) as amount
from (values ('a', 1.50), ('b', 2.25)) as t(code, amount)

Through an SSH bastion. When the database is only reachable from a jump host, add an ssh: block. host and port are then the database’s address as the bastion sees it. dre opens the SSH session itself; there’s no ssh -L to run and no local port to keep open.

connections:
warehouse:
targets:
prod:
type: postgres
host: db.internal # as seen from the bastion
port: 5432
user: reporting
password: "{{ env_var('PG_PASSWORD') }}"
database: analytics
sslmode: verify-full # still checks db.internal's certificate
sslrootcert: ~/certs/ca.pem
ssh:
host: bastion.example.com
username: deploy
private_key_path: ~/.ssh/id_ed25519
# or the key's text, e.g. a CI secret:
# private_key: "{{ env_var('BASTION_SSH_KEY') }}"
host_key_fingerprint: "SHA256:..." # or known_hosts_path

The ssh: block takes the same settings as the sftp destination: host, port (22), username, and password, private_key_path or private_key (+ private_key_passphrase), or use_agent: true, and allow_rsa_keys (see RSA keys); the bastion’s host key is checked against known_hosts_path (default ~/.ssh/known_hosts) or a pinned host_key_fingerprint, and an unknown or changed key is refused (there’s no accept_unknown_host here). The error for an unknown key prints its fingerprint, ready to pin. connect_timeout covers the whole way, SSH included, and errors say which hop failed: the bastion, the bastion’s connection to the database, or Postgres itself. Templates can’t read the ssh block (it may hold a key), and dre init doesn’t ask for it.

A connection error names the server (host:port/database). On macOS the plugin uses the system TLS stack: TLS 1.2 at most, and with verify-ca/verify-full a server certificate valid for more than 825 days is rejected (Apple’s limit), so issue server certificates for 825 days or less.

Check the connection before porting a report

Section titled “Check the connection before porting a report”

For a minimal direct connection, use:

connections:
warehouse:
targets:
dev:
type: postgres
host: localhost
user: reporting
database: analytics
password: "{{ env_var('DRE_SECRET_PG_PASSWORD') }}"

Copy the tutorial project’s report structure, declare postgres, and start with select 1 as connection_check before replacing the SQL with business queries. Run dre validate --live <report> to check SQL without executing it. Adapt the complete monthly finance example after loading its sample data into Postgres; replace any DuckDB-specific SQL with PostgreSQL equivalents.

invalid-connection-setting means the profile shape needs fixing before connecting. connection-failed names the server: check host, port, credentials and TLS. query-failed on a relation checks database/schema names and the reporting role’s permissions. See connection reference, error codes, and connection.