Connect PostgreSQL with Statisfy
The PostgreSQL integration lets you import data from any PostgreSQL-compatible database into Statisfy — your application database, an analytics replica, or any Postgres-wire-compatible engine. Author SQL queries in the Statisfy settings UI, preview results, and schedule them. PostgreSQL uses the same self-serve configuration model as the other warehouse integrations. You can find the shared concepts — query types, account resolvers, transformers, schedules, configuration history — in Integration Concepts. This page focuses on what’s specific to PostgreSQL.Video Tutorial
Prerequisites:- Admin access to Statisfy
- A PostgreSQL instance reachable from Statisfy’s egress IPs (see Network Access)
- A database user with
SELECTaccess on the schemas/tables you want to sync
What You Can Import
Set Up the Database User
Run as a Postgres superuser (or a user withCREATE ROLE):
analytics and public with the database and schema(s) you want Statisfy to read.
Steps to Connect
- Log in to Statisfy.
- Navigate to Integrations → Admin Apps → PostgreSQL → Connect.
-
Enter your connection details:
- Host — DNS name or IP of the database
- Port — Default
5432 - Database — Database name
- Username —
statisfy_reader(or whichever read-only user you created) - Password — The user’s password
- SSL Mode —
requireis recommended; useverify-fullif you’ve installed your CA cert
- Click Connect.
- Once connected, PostgreSQL will appear as Connected on the Integrations page. To confirm Statisfy can reach PostgreSQL and authenticate, click the gear (Settings) on the card, then Test Connection on the Connection card.
Configure Queries
Open Integrations → PostgreSQL → Settings to:- Browse schemas and tables the user can see, with column types
- Author queries using Postgres SQL with autocomplete and a preview pane
- Map results to Statisfy accounts (via Statisfy account ID, CRM ID, organization ID, email domain, account name, or any custom field) and to fields, metrics, or custom objects
- Apply column transformers (
strip_prefix,regex_extract,lookup, etc.) to reshape values before they’re written - Set the cadence — daily, weekly, monthly, or a sub-day interval (HOURLY through TWELVE_HOURS)
- Run a one-off sync on demand
product_usage, custom_field, or custom_object. See Query types, Account resolvers, and Query configuration dialog for the shared model and how to write, preview, and map a query.
If a schema and table allowlist is saved, Statisfy only lets you save, preview, and browse data inside it. After each sync, check Recent runs for how many rows each query wrote, failed, didn’t match, had nothing to write, or filtered out. See Recent runs.
PostgreSQL-Specific Notes
- Date placeholders. Use
{START_DATE}/{END_DATE_SQL}inWHEREclauses to keep queries incremental. Postgres’sDATE_TRUNC(),INTERVAL, and::datecasts compose naturally with these. - Schema search path. Statisfy does not rely on
search_path— queries should fully qualify tables (schema.table) when they live outsidepublic. - Read isolation. For long-running scans, consider
SET TRANSACTION ISOLATION LEVEL REPEATABLE READin the query if you need a consistent snapshot — but in most cases the default isolation is fine.
Account Matching
For
custom_field queries that target people instead of accounts, configure a person resolver (email column, optionally name) — Statisfy will upsert the person record by email.
Sync Behavior
Scheduled Jobs:- Each saved query runs on its own cadence.
- The first run after connecting is a bootstrap covering the last 30 days; subsequent runs cover only the active window for the cadence.
- Self-serve configuration takes precedence over any built-in fallback set up by support.
- Per-query errors are logged but do not block other queries from running.
- Invalid rows within a query are skipped and reported in the job audit log.
Network Access
If your Postgres host has IP allowlisting or is in a private network, allow Statisfy’s egress IPs:Security
- Credentials are stored encrypted in Google Cloud Secret Manager.
- All connections use TLS — Statisfy refuses to connect over plaintext when
ssl_modeis set torequireor higher. - Queries authored in the Settings page are read-only — Statisfy validates each query and rejects DDL/DML before save.
- Access is scoped to the database user you provide — grant
SELECTonly on the schemas you want Statisfy to read.
Troubleshooting
Connection test fails
Connection test fails
Check network access:
- Verify the host is reachable from the Statisfy egress IPs above
- Confirm the firewall / security group allows inbound traffic on the Postgres port (default
5432) - Confirm the database accepts SSL connections (check
pg_hba.conf)
- Verify host, port, database, username, and password
- Confirm the user has
CONNECTprivilege on the database
Schema or tables not visible in the browser
Schema or tables not visible in the browser
- Confirm the database user has
USAGEon the schema andSELECTon the tables - System schemas (
pg_catalog,information_schema,pg_toast) are intentionally hidden - New grants may require closing and reopening the schema picker
Query validation errors at save time
Query validation errors at save time
- Statisfy validates queries against the Postgres dialect — vendor-specific functions from other warehouses will be flagged
- DDL (
CREATE,DROP,ALTER) and DML (INSERT,UPDATE,DELETE) are rejected — only read-only queries are allowed - Check the validation error for the offending function or syntax
Records not matching to accounts
Records not matching to accounts
- Verify the resolver column contains values that exist in Statisfy
- For CRM ID resolvers, confirm your CRM integration has synced the matching accounts
- Try a different resolver (switch from account name to email domain) if matching is unreliable
- Add a
regex_extractorstrip_prefixtransformer if the column contains the right ID with extra characters
Sync is slow or impacting production
Sync is slow or impacting production
- Point Statisfy at a read replica instead of the primary
- Lower the cadence to
DAILYso each run scans a smaller window - Use
{START_DATE}/{END_DATE_SQL}to keep queries incremental - Add indexes on the columns you filter on