Postgres

The conformance oracle. `ON CONFLICT` merge, transactional.

Every destination receives the same layout; see the tables Ingest creates.

Setup

Ingest connects as a normal Postgres user over TLS and needs to own its own schema: create tables in it, write and read them, alter them when your source adds a column, and drop the scratch schema the connection test makes. It never needs superuser, and it never touches schemas you do not grant.

Create a role for it

Run this as a user that can create roles, substituting your own password and database name:

CREATE ROLE ingest LOGIN PASSWORD 'a-long-random-password';
GRANT CONNECT ON DATABASE your_db TO ingest;
GRANT CREATE ON DATABASE your_db TO ingest;

CREATE ON DATABASE is the one that matters and the one usually missed: Ingest creates a schema per dataset, and a role without it connects perfectly and then fails on the first write. If you would rather create the schema yourself and keep database-level creation off, do that and grant instead:

CREATE SCHEMA your_dataset AUTHORIZATION ingest;

Owning the schema is simpler than enumerating table grants, because Ingest creates tables as it goes and per-table grants cannot be given in advance. If your policy forbids ownership, GRANT USAGE, CREATE ON SCHEMA your_dataset TO ingest plus ALTER DEFAULT PRIVILEGES is the equivalent.

Reachable from the internet

Ingest runs on its own fleet and egresses from a public address; it has no route into your VPC. The endpoint has to be reachable from the internet, and your security group or pg_hba.conf has to allow Ingest's egress address. A destination on a private address fails the connection test with that as the stated reason rather than a generic timeout.

What to paste

Connection string: postgresql://ingest:password@host:5432/your_db?sslmode=require. It is stored as a secret, in your own namespace, and never returned to the browser.

Then test it

Test connection creates a scratch schema and a table, writes a few rows through the same load path a real run uses, reads them back to check the count is exactly right, round-trips pipeline state, and drops the lot. That proves the CREATE grant and the write, rather than just the password.

Staging

needs_staging: none. Staging always happens in the destination's own cloud and region; data does not take a detour through ours.

Conformance

Every adapter passes the same suite before it ships: create a table with every canonical type, append 100k rows, atomic replace, merge (latest dedup_sort wins; child tables delete-then-insert by root id), schema evolution, NULL-key rejection, package replay without duplicates, state and schema round-trip, row-count read-back, identifier edge cases, double-underscored table names (__quarantine, child tables), and rollback on a mid-load failure.