Skip to content

PostgreSQL clients

View Markdown

Because PizzaSQL speaks the PostgreSQL wire protocol, nearly any PostgreSQL client works out of the box. The only adjustments are the ones described in Connect:

  • Host db.database.pizza, port 5432.
  • Database name acme/production (slash included).
  • Password is your API key; the user field is ignored.
  • sslmode=disable — TLS is currently declined by the proxy.
postgresql://u:pz_live_REPLACE_ME@db.database.pizza:5432/acme%2Fproduction?sslmode=disable

Use this everywhere a client accepts a URI. The / in the database name is percent-encoded as %2F.

Terminal window
# Interactive
PGPASSWORD='pz_live_REPLACE_ME' psql \
"postgresql://u@db.database.pizza:5432/acme%2Fproduction?sslmode=disable"
# Single command
PGPASSWORD='pz_live_REPLACE_ME' psql \
"postgresql://u@db.database.pizza:5432/acme%2Fproduction?sslmode=disable" \
-c "SELECT * FROM users LIMIT 5;"
# Run a script
PGPASSWORD='pz_live_REPLACE_ME' psql \
"postgresql://u@db.database.pizza:5432/acme%2Fproduction?sslmode=disable" \
-f schema.sql

pgcli works the same way:

Terminal window
pgcli "postgresql://u:pz_live_REPLACE_ME@db.database.pizza:5432/acme%2Fproduction?sslmode=disable"

DBeaver, DataGrip, TablePlus, and pgAdmin all connect using the connection type PostgreSQL:

  • Host: db.database.pizza
  • Port: 5432
  • Database: acme/production
  • User: u (any value)
  • Password: your API key
  • SSL: off / disable

Most GUIs use discrete fields, so enter acme/production literally — no %2F encoding needed.

import { Client } from 'pg';
const client = new Client({
host: 'db.database.pizza',
port: 5432,
user: 'u',
password: process.env.PZ_API_KEY,
database: 'acme/production', // discrete field, no encoding
ssl: false,
});
await client.connect();
const res = await client.query('SELECT * FROM users WHERE id = $1', [1]);
console.log(res.rows);
await client.end();

See JavaScript for a fuller walkthrough.

import os
import psycopg
conn = psycopg.connect(
host="db.database.pizza",
port=5432,
user="u",
password=os.environ["PZ_API_KEY"],
dbname="acme/production",
sslmode="disable",
)
cur = conn.cursor()
cur.execute("SELECT * FROM users WHERE id = %s", (1,))
print(cur.fetchall())
conn.close()

See Python for more.

import (
"github.com/jackc/pgx/v5"
)
conn, err := pgx.Connect(ctx,
"postgresql://u:pz_live_REPLACE_ME@db.database.pizza:5432/acme%2Fproduction?sslmode=disable")

PizzaSQL accepts both ? (SQLite style) and $1, $2 (PostgreSQL style) placeholders. Prefer the style your driver parameterizes natively — most Postgres drivers use $1, $2.

-- PostgreSQL style
SELECT * FROM invoices WHERE user_id = $1 AND status = $2;
-- SQLite style
SELECT * FROM invoices WHERE user_id = ? AND status = ?;

The SQL you send is SQLite-compatible, not PostgreSQL. That means:

  • INTEGER PRIMARY KEY, not SERIAL; values are assigned when omitted.
  • TEXT, not VARCHAR(n) with enforced length.
  • No schemas, roles, ARRAY, JSONB, or ENUM types.
  • No RETURNING-heavy Postgres-specific features; check Compatibility first.

The SQL reference is the source of truth for what’s supported.

The PostgreSQL protocol supports the full transactional surface — BEGIN, COMMIT, ROLLBACK, SAVEPOINT — unlike the HTTP API, which rejects transaction statements. Use this surface when you need multi-statement atomicity. See Transactions.