Skip to main content

Data Architecture

Cross-module overview of how Planning Center data is organized and interconnected in Parable

Overview

Parable integrates with 8 Planning Center modules, each representing a different aspect of church management. This page provides a high-level view of how these modules connect and share data.

Module Overview

Planning Center modules and their relationships

Open diagram in new tab →

Module Interconnections

People as the Central Hub

The People module is the foundation of the entire system. Nearly every other module references people in various roles:

  • Giving: People as donors, joint givers, and batch creators
  • Groups: People as group members, leaders, and owners
  • Check-ins: People checking in to events
  • Services: People as team members, leaders, and plan assignees
  • Calendar: People as event creators and resource bookers
  • Registrations: People as registrants and attendees
  • Publishing: People as speakers and content creators

Key Principles:

  1. Sequential Processing: Workflows execute sequentially to respect dependencies (People before Giving, etc.)
  2. Bulk Operations: Data is collected and inserted in batches for performance
  3. Multi-tenant Isolation: Row-level security ensures tenant data separation
  4. Heartbeat Pattern: Long-running activities send heartbeats to prevent timeouts

Database Schema Organization

All Planning Center data is stored in the planning_center schema with prefixed table names:

planning_center.{module}_{entity}

Examples

  • planning_center.people_people - People entities
  • planning_center.people_households - Household entities
  • planning_center.giving_donations - Donation entities
  • planning_center.groups_groups - Group entities
  • planning_center.services_plans - Service plan entities

Common Patterns Across All Modules

Every table follows these patterns:

System Fields

All tables include:

  • system_status - All tables have a system_status column that filters to only show active records
  • system_created_at - When record was first created
  • system_updated_at - Last modification timestamp
  • tenant_organization_id - All tables have a tenant_organization_id column that filters to only show records for the current organization

Entity ID Pattern

All entities store their Planning Center ID:

  • {entity}_id - Original Planning Center identifier (e.g., people_id, donation_id)

Row Level Security (RLS)

All tables have RLS policies that automatically:

  • Filter data by current database role
  • Ensure tenant isolation
  • Restrict access to system_status = 'active' records

Module Details

People Module (97 tables)

Core Entities:

  • People, Households, Household Memberships
  • Addresses, Emails, Phone Numbers
  • Campuses, Organizations
  • Forms, Form Submissions
  • Workflows, Workflow Cards
  • Lists, Notes, Messages

Complexity: Highest - manages the foundational identity layer

Key Relationship Pattern: Heavy use of relationship tables for flexible associations

Giving Module (27 tables)

Core Entities:

  • Donations, Batches, Batch Groups
  • Pledges, Pledge Campaigns
  • Recurring Donations, Refunds
  • Designations, Funds
  • Payment Methods, Payment Sources

Dependencies: Requires People (donors), Campuses

Key Feature: Financial transaction tracking with audit trails

Groups Module (28 tables)

Core Entities:

  • Groups, Group Types
  • Memberships, Enrollments
  • Events, Event Notes, Attendance
  • Locations, Resources, Tags

Dependencies: Requires People (members, leaders)

Key Feature: Community organization and event management

Check-ins Module (41 tables)

Core Entities:

  • Check-ins, Check-in Groups
  • Events, Event Times, Event Periods
  • Locations, Location Labels
  • Person Events, Attendance Types
  • Stations, Passes, Themes

Dependencies: Requires People (attendees), Events

Key Feature: Event attendance tracking with label printing

Services Module (54 tables)

Core Entities:

  • Service Types, Plans, Plan Times
  • Teams, Team Positions
  • Songs, Arrangements, Keys
  • Items, Media, Schedules
  • Blockouts, Signup Sheets

Dependencies: Requires People (team members), potentially Groups

Key Feature: Complex worship service planning

Calendar Module (42 tables)

Core Entities:

  • Events, Event Instances, Event Times
  • Resources, Resource Bookings
  • Room Setups, Resource Questions
  • Conflicts, Attachments, Feeds

Dependencies: Integrates with Groups, Services, Check-ins events

Key Feature: Centralized event and resource management

Registrations Module (14 tables)

Core Entities:

  • Registrations, Signups
  • Attendees, Emergency Contacts
  • Categories, Selection Types
  • Locations, Campuses

Dependencies: Requires People (registrants)

Key Feature: Event registration and attendee management

Publishing Module (17 tables)

Core Entities:

  • Channels, Channel Times
  • Episodes, Episode Times, Episode Resources
  • Series, Speakers, Speakerships
  • Note Templates

Dependencies: Requires People (speakers), potentially Services (sermons)

Key Feature: Sermon and content publishing workflow

Performance Characteristics

Table Sizes (Approximate)

Based on typical church databases:

ModuleTablesEst. Rows (Small Church)Est. Rows (Large Church)
People8410K - 50K500K - 2M
Giving245K - 20K200K - 1M
Groups251K - 5K50K - 200K
Check-ins265K - 20K100K - 500K
Services55+2K - 10K50K - 200K
Calendar271K - 5K20K - 100K
Registrations14500 - 2K10K - 50K
Publishing15100 - 1K5K - 20K

Sync Performance

  • Full sync time: 5 minutes - 2 hours (depends on data size)
  • Typical interval: Every 24 hours
  • Bulk insert performance: 1K-10K rows/second per table

Multi-Tenant Architecture

Tenant Isolation

Multi-tenant architecture with row-level security

Open diagram in new tab →

Key Security Features:

  1. Role-based access: Each tenant has a dedicated database role
  2. Automatic filtering: Views filter by CURRENT_ROLE to show only tenant's data
  3. No cross-tenant queries: Impossible to access other tenants' data
  4. Schema-level isolation: All Planning Center data in dedicated schema

Common Query Patterns

Cross-Module Queries

Example: Find all donations from a specific group's members

-- Get all donations from small group members
WITH group_members AS (
    SELECT DISTINCT mr.relationship_id as person_id
    FROM planning_center.groups_memberships m
    JOIN planning_center.groups_memberships_relationships mr
        ON mr.membership_id = m.membership_id AND mr.relationship_type = 'Person'
    JOIN planning_center.groups_memberships_relationships mgr
        ON mgr.membership_id = m.membership_id AND mgr.relationship_type = 'Group'
    WHERE mgr.relationship_id = 'group_123'
)
SELECT
    p.first_name,
    p.last_name,
    d.amount_cents / 100.0 AS amount,
    d.received_at,
    f.name AS fund_name
FROM group_members gm
JOIN planning_center.people_people p
    ON gm.person_id = p.person_id
JOIN planning_center.giving_donations_relationships dr
    ON dr.relationship_id = p.person_id
    AND dr.relationship_type = 'Person'
JOIN planning_center.giving_donations d
    ON d.donation_id = dr.donation_id
JOIN planning_center.giving_donations_relationships ddr
    ON ddr.donation_id = d.donation_id
    AND ddr.relationship_type = 'Designation'
JOIN planning_center.giving_designations des
    ON des.designation_id = ddr.relationship_id
JOIN planning_center.giving_designations_relationships desr
    ON desr.designation_id = des.designation_id
    AND desr.relationship_type = 'Fund'
JOIN planning_center.giving_funds f
    ON f.fund_id = desr.relationship_id
WHERE d.received_at >= DATE_TRUNC('year', CURRENT_DATE)
ORDER BY d.received_at DESC;

Example: Find people who are both group leaders and service team members

-- Find people serving in both groups and services
WITH group_leaders AS (
    SELECT DISTINCT mr.relationship_id as person_id
    FROM planning_center.groups_memberships m
    JOIN planning_center.groups_memberships_relationships mr
        ON mr.membership_id = m.membership_id AND mr.relationship_type = 'Person'
    WHERE m.role = 'leader'
),
service_team AS (
    SELECT DISTINCT pp.person_id
    FROM planning_center.services_plan_people pp
    WHERE pp.status = 'C'  -- Confirmed
)
SELECT
    p.first_name,
    p.last_name,
    COUNT(DISTINCT mgr.relationship_id) AS groups_led,
    COUNT(DISTINCT pp.plan_id) AS services_on
FROM planning_center.people_people p
JOIN group_leaders gl ON p.person_id = gl.person_id
JOIN service_team st ON p.person_id = st.person_id
LEFT JOIN planning_center.groups_memberships_relationships mr
    ON mr.relationship_type = 'Person' AND mr.relationship_id = p.person_id
LEFT JOIN planning_center.groups_memberships gm
    ON gm.membership_id = mr.membership_id AND gm.role = 'leader'
LEFT JOIN planning_center.groups_memberships_relationships mgr
    ON mgr.membership_id = gm.membership_id AND mgr.relationship_type = 'Group'
LEFT JOIN planning_center.services_plan_people pp
    ON pp.person_id = p.person_id
GROUP BY p.person_id, p.first_name, p.last_name
ORDER BY groups_led DESC, services_on DESC;

Next Steps

Explore specific module data models:

Additional Resources

API Reference

Query the Planning Center data via API

On this page