Accessing Your Data
Query your synced church data from the SQL editor, a database client, or a BI tool
Parable gives you two ways to query your synced Planning Center data directly: the built-in SQL editor, and a read-only PostgreSQL connection you can point any tool at.
Option 1: The Built-In SQL Editor
The fastest path — nothing to install or configure.
Open SQL Editor from the sidebar. It includes:
- Schema browsing and autocomplete across every synced table
- Query history and saved queries
- CSV export, including background export for large result sets
- Query cancellation for long-running work
Start here. Use an external client only when you need a tool Parable doesn't provide — scheduled extracts, a BI semantic layer, or a notebook workflow.
Option 2: Your Own Database Client or BI Tool
Getting Your Connection String
Select Create Connection and give it a name you'll recognize (for example, "Power BI" or "Michael's laptop").
Parable generates and displays the username, password, host, database name, and a complete connection string.
The password is stored encrypted, and you can reopen it later — press Connect on the connection under Settings → Database to see the password and full connection string again. You can hold several connections at once and revoke them individually.
Your connection string looks like this:
postgres://username:password@host:5432/databaseYou don't supply a database — Parable hosts the warehouse and provisions a dedicated role scoped to your organization.
What the Connection Can Do
The role Parable creates is deliberately narrow:
| Access | SELECT only |
| Schema | planning_center, plus the giving_custom_units tables used by custom giving reports |
| Isolation | Row-level security restricts every query to your organization |
| Filtering | Only active records are visible by default |
You cannot create tables, views, materialized views, or indexes through this
connection, and you cannot write to any table. INSERT, UPDATE, DELETE, and
DDL will all be rejected. This is by design — your Planning Center data stays
authoritative and unmodified.
A "permission denied" error on a write or CREATE statement is not a
misconfiguration. It's the guardrail working.
Connecting a Database Client
- Click + to create a new connection and choose PostgreSQL
- Fill in Host, Port (5432), User, Password, and Database from your Parable credentials
- Set SSL mode to Require
- Test, then Connect
Connecting a BI Tool
Get Data → PostgreSQL database. Enter the host and database name, choose DirectQuery for live data or Import for a cached extract, then supply the username and password when prompted.
Import mode is usually the better choice — it keeps report interactions fast and reduces load on the warehouse.
Understanding the Schema
All synced Planning Center data lives in the planning_center schema, named
{app}_{entity}:
-- List everything available to you
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'planning_center'
ORDER BY table_name;Common starting points:
| Table | Contains |
|---|---|
planning_center.people_people | Every person record |
planning_center.people_households | Household groupings |
planning_center.giving_donations | Individual donations |
planning_center.giving_funds | Fund definitions |
planning_center.checkins_check_ins | Attendance check-ins |
planning_center.groups_groups | Small groups and classes |
planning_center.groups_memberships | Group membership records |
planning_center.services_plans | Worship service plans |
planning_center.calendar_events | Church calendar events |
planning_center.registrations_signups | Event signups |
Relationships Live in Their Own Tables
This is the single most important thing to know before writing queries. Entity
tables carry no foreign-key columns. Every link between records lives in a
matching *_relationships table:
-- A donation's donor is NOT giving_donations.person_id.
-- It's a row in giving_donations_relationships.
SELECT
p.first_name,
p.last_name,
d.amount_cents / 100.0 as amount,
d.received_at
FROM planning_center.giving_donations d
JOIN planning_center.giving_donations_relationships dr
ON dr.donation_id = d.donation_id
AND dr.relationship_type = 'Person'
JOIN planning_center.people_people p
ON p.person_id = dr.relationship_id
WHERE d.payment_status = 'succeeded'
ORDER BY d.received_at DESC
LIMIT 100;Each relationship table has three meaningful columns: the parent entity's ID
(named after the parent table, for example donation_id), relationship_type
(what kind of record it points at), and relationship_id (the ID of that
record).
See Planning Center Overview for the full model, and each module's data-model page for its relationship types.
First Queries
-- How many active people do we have?
SELECT COUNT(*) as active_people
FROM planning_center.people_people
WHERE status = 'active';-- Giving by month over the last year
SELECT
DATE_TRUNC('month', received_at) as month,
COUNT(*) as gifts,
SUM(amount_cents) / 100.0 as total_dollars
FROM planning_center.giving_donations
WHERE payment_status = 'succeeded'
AND received_at >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY DATE_TRUNC('month', received_at)
ORDER BY month DESC;-- Group participation
SELECT
g.name as group_name,
COUNT(DISTINCT mr_person.relationship_id) as members
FROM planning_center.groups_groups g
JOIN planning_center.groups_memberships_relationships mr_group
ON mr_group.relationship_id = g.group_id
AND mr_group.relationship_type = 'Group'
JOIN planning_center.groups_memberships_relationships mr_person
ON mr_person.membership_id = mr_group.membership_id
AND mr_person.relationship_type = 'Person'
WHERE g.archived_at IS NULL
GROUP BY g.name
ORDER BY members DESC;Best Practices
Let Row-Level Security Do Its Job
Every query is automatically scoped to your organization and to active
records. Adding these filters yourself is redundant and can slow queries down:
- ❌
WHERE tenant_organization_id = 1 - ❌
WHERE system_status = 'active'
Understand the Two Kinds of Timestamp
created_at/updated_at— when the record changed in Planning Center. Use these for ministry metrics.system_created_at/system_updated_at— when Parable synced the record. Use these to debug sync behavior, not to measure ministry.
Query Performance
- Filter by date range before joining relationship tables
- Add
LIMITwhile exploring - Select the columns you need rather than
SELECT *on large tables - Cache heavy summaries in your BI tool — you can't create materialized views through this connection
Security
- Treat the connection string like a password; never commit it or share it publicly
- Create a separate connection per tool or person so you can revoke one without disrupting the others
- Delete connections you no longer use from Settings → Database
Troubleshooting
"Could not connect to server" Confirm the host and port (5432) are exactly as shown in Settings → Database, and that SSL is enabled in your client.
"Authentication failed" Passwords can't be recovered after creation. If you don't have it saved, delete the connection and create a new one.
"Permission denied" on a write or CREATE
Expected. The connection is read-only by design.
A table looks empty Check that the corresponding Planning Center app is connected and has finished its first sync under Settings → Sync.
Getting Help
- Ask in the community Slack
- Email michael@getparable.io
- Browse module-specific query examples under Planning Center