Postgres
Postgres node reference - all 21 operations, the credential it needs, and a worked example.
Reads and writes a Postgres database: rows without SQL (select, get one, count, insert, bulk insert, update, upsert, delete, truncate), transactions, EXPLAIN plans, stored procedures and functions, schema discovery, and raw parameterized SQL.
Credential: Postgres connection string - see Credentials.
Privileges
Each operation below lists the privilege it needs. Privileges are GRANTed to the database role in the connection string. Postgres has no scopes and no consent screen - the equivalent question is which SQL privilege the connecting role holds on the object, which is exactly what a permission denied for table ... error is asking for. Narrow the blast radius by connecting as a role granted only what the workflow needs. If a run fails with a permission error, the node names the missing privilege in the error - grant it and re-run; you do not need to rebuild the workflow.
Operations (21)
Rows — read
| Operation | What it does | Privilege |
|---|---|---|
selectRows | Select rows | SELECT on the table |
getRow | Get one row | SELECT on the table |
countRows | Count rows | SELECT on the table |
Rows — write
| Operation | What it does | Privilege |
|---|---|---|
insertRow | Insert a row | INSERT on the table |
insertRows | Insert many rows | INSERT on the table |
updateRows | Update rows | UPDATE on the table (and SELECT for the filter) |
upsertRow | Insert or update a row | INSERT and UPDATE on the table |
upsertRows | Insert or update many rows | INSERT and UPDATE on the table |
deleteRows | Delete rows | DELETE on the table (and SELECT for the filter) |
truncateTable | Empty a table (truncate) | TRUNCATE on the table |
SQL
| Operation | What it does | Privilege |
|---|---|---|
executeQuery | Run a SQL query | Whatever the statement itself needs |
executeTransaction | Run statements in a transaction | Whatever the statements themselves need |
explainQuery | Explain a query plan | SELECT on everything the plan touches |
Procedures & functions
| Operation | What it does | Privilege |
|---|---|---|
callProcedure | Call a stored procedure | EXECUTE on the procedure |
callFunction | Call a function | EXECUTE on the function |
Schema
| Operation | What it does | Privilege |
|---|---|---|
listSchemas | List schemas | Connect — information_schema shows only what the role can see |
listTables | List tables | Connect — information_schema shows only what the role can see |
listColumns | List columns | Connect — information_schema shows only what the role can see |
listIndexes | List indexes | Connect — pg_indexes shows only what the role can see |
listConstraints | List keys and constraints | Connect — information_schema shows only what the role can see |
getServerInfo | Get server info | Connect |
Example
Insert an order row without writing any SQL
A webhook delivers an order and it needs to land in Postgres. Before SW20.1 the only way to do that was to write the INSERT by hand and interpolate the payload into the statement text — which is how the node became a SQL console for whoever could reach the webhook. Every value below is sent as a bound parameter, so a customer literally named Robert'); DROP TABLE orders;-- is stored, not executed.
Set Operation to insertRow, then fill in:
| Field | Value | Notes |
|---|---|---|
schema | public | Optional; defaults to the search path |
table | orders | Identifiers are escape-quoted, never interpolated |
values | {"customer_email": "{{ myTrigger.email }}", "total_cents": "{{ myTrigger.totalCents }}", "status": "paid"} | Always bound as $1, $2, $3 — an expression here can never become SQL |
returning | id, created_at | Postgres can hand back the row it just wrote; MySQL cannot, which is why that node exposes insertId instead |
Sets {{order.rows}} (the RETURNING columns, so {{order.rows.[0].id}} is the new primary key), {{order.rowCount}} and {{order.truncated}}.