Direct SQL – Ponder
Skip to content

Direct SQL

Query indexed data directly in Postgres

It's often useful to query Ponder tables directly in Postgres.

Limitations

As a rule of thumb, the only supported operation is SELECT queries against Ponder tables.

  • Direct SQL queries are read-only. Direct SQL queries should not insert, update, or delete rows from Ponder tables.
  • Direct SQL with zero-downtime deployments requires additional setup. Read more about the views pattern in the production guide.
  • Triggers on Ponder tables are not supported.

Database schema

Ponder uses database schemas to isolate deployments. Read more in the self-hosting guide.

Direct SQL queries should target the database schema corresponding to a specific deployment. Or, if your project uses the views pattern (recommended), queries should target the views schema.

Here are a few strategies to configure the database schema.

Manual / hard-coded

The easiest way to target a specific database schema is to specify it manually in each SQL query. This works well for projects using the views pattern, because the schema changes less frequently.

Direct SQL query
SELECT *
FROM my_ponder_project.accounts -- Database schema specified
ORDER BY created_at ASC
LIMIT 100;

Search path

Another approach is to write direct SQL queries using unqualified table names (no database schema specified), then update the search_path setting to include the target database schema.

Set search path
SET search_path TO my_ponder_project, "$user", public;

Drizzle (setDatabaseSchema)

If you're writing direct SQL queries using Drizzle (e.g. from a downstream Node.js application), you can use the setDatabaseSchema utility function to target a specific database schema.

This function mutates a Drizzle schema such that any queries built using that schema will target the specified database schema. Read more in the Drizzle documentation.

Drizzle
import { drizzle } from "drizzle-orm/node-postgres";
import * as schema_ from "../../ponder/ponder.schema"; 
 
const schema = setDatabaseSchema(schema_, "target_schema"); 
 
const db = drizzle(process.env.DATABASE_URL, { schema, casing: "snake_case" });
 
const oldAccounts = await db
  .select()
  .from(schema.accounts)
  .orderBy(asc(schema.accounts.createdAt))
  .limit(100);