Direct SQL queries
This guide describes how to query the database directly using psql or Drizzle.
Don't write to onchain tables from external clients. Only write to onchain tables from indexing functions.
Direct SQL queries against PGlite are possible, but the methods described here do not work out of the box.
psql
You can also use psql, a terminal-based Postgres front-end, to query the database from the command line.
Connection string
Connect using the same connection string that your Ponder app uses.
psql 'postgresql://username:password@localhost:5432/your_database'
Display tables
Use the \dt
command to list all tables in the public
schema. If you are using a schema other than public
, include the pattern.
\dt
\dt my_schema.*
The reorg
tables are used by Ponder internally during reorg reconciliation, and the _ponder_meta
table is used to store metadata about the database state.
List of relations
Schema | Name | Type | Owner
--------+-----------------------------+-------+----------
public | accounts | table | username
public | transfer_events | table | username
public | _ponder_meta | table | username
public | _reorg__accounts | table | username
public | _reorg__transfer_events | table | username
(5 rows)
Select rows
Select a few rows from the accounts
table.
SELECT * FROM accounts LIMIT 5;
address | balance |
--------------------------------------------+-------------------------+
0xf73fe15cfb88ea3c7f301f16ade3c02564aca407 | 10000000000000000000000 |
0xb0659bc97ed61b37d6b140f3e12a41d471781714 | 20000000000000000000000 |
0x52932f5b2767d917c3134140168f2176c94e8b2c | 10000000000000000000000 |
0xfb7ca75b3ce099120602b5ab7104cff030ee43f8 | 0 |
0x9ccc6c5a9d25429f55ad9af6363c1c4f16b179ad | 7000000000000000000000 |
(5 rows)
Aggregate data
Find the total number of transfers sent to each account.
SELECT "to", COUNT(*) AS transfer_count
FROM transfer_events
GROUP BY "to"
ORDER BY transfer_count DESC
LIMIT 5;
to | transfer_count
--------------------------------------------+----------------
0x5d752f322befb038991579972e912b02f61a3dda | 2342
0x1337f7970e8399ccbc625647fce58a9dada5aa66 | 313
0x9726041047644626468922598128349778349982 | 306
0x27239549dd40e1d60f5b80b0c4196923745b1fd2 | 256
0x450638daf0caedbdd9f8cb4a41fa1b24788b123e | 238
(5 rows)
Drizzle
As of 0.8
, the onchainTable
objects are not automatically aware of the
database schema that your instance is using. To get this working, you'll need
to 1) use the public
schema or 2) set the connection search path to the
schema that your instance is using. We're tracking this issue
here.
The onchainTable
objects exported by ponder.schema.ts
are valid Drizzle table objects. You can import them from TypeScript files outside the Ponder src/
directory and use them with the Drizzle query builder.
Here's a script that creates a Drizzle client and runs a query against the Ponder tables. Be sure to connect to the database using the same DATABASE_URL
as the Ponder app.
import { drizzle } from "drizzle-orm/node-postgres";
import * as schema from "../../ponder/ponder.schema";
const db = drizzle(process.env.DATABASE_URL, { schema, casing: "snake_case" });
// Select
const oldAccounts = await db
.select()
.from(schema.accounts)
.orderBy(asc(schema.accounts.createdAt))
.limit(100);
// Query
const whalesWithTransfers = await db.query.accounts.findMany({
where: (accounts, { eq }) => eq(accounts.balance, 1_000_000n),
with: { transferEvents: true },
});