Planning Center Calendar Data Model
This document provides complete documentation of the Planning Center Calendar data model in Parable, including all tables, fields, and relationships.
Overview
The Calendar module contains 22 entity tables and 6 relationship tables supporting event management, resource booking, scheduling, and calendar synchronization.
Visual Data Model
The diagram below shows the core entities and their relationships in the Calendar module. Use it as a visual reference while exploring the detailed table definitions below.
Core Entity Relationships
Open diagram in new tab →
Key Relationships Explained
Event Hierarchy:
EVENT is the master event (e.g., “Sunday Service”)
EVENT_INSTANCE is a specific occurrence (e.g., “Sunday Service on Jan 15, 2024”)
EVENT_TIME breaks instances into periods (Setup 8am-9am, Event 9am-11am, Teardown 11am-12pm)
Resource Booking:
RESOURCEs are bookable items (rooms, equipment, vehicles)
RESOURCE_FOLDERs organize resources hierarchically
RESOURCE_BOOKING links resources to event instances
ROOM_SETUP defines different configurations for room resources
Approval Workflow:
EVENT_RESOURCE_REQUEST initiates booking request
REQUIRED_APPROVAL specifies which groups must approve
RESOURCE_APPROVAL_GROUP contains approvers
RESOURCE_QUESTION collects additional information during booking
Conflict Management:
CONFLICT tracks resource double-bookings
- Links winner (approved booking) and loser (rejected booking)
- Resolved when winner is selected
Cross-App Connections:
EVENT_CONNECTION links calendar events to other Planning Center modules
- Connected to Services (worship plans), Groups (group events), etc.
- Enables unified scheduling across the platform
Generic Relationship Pattern:
- Event metadata via
calendar_events_relationships
Query Requirements
Schema Prefix
IMPORTANT: All tables in the Planning Center Calendar module are in the planning_center schema. You MUST prefix all table names with planning_center. in your queries.
✅ CORRECT: SELECT * FROM planning_center.calendar_events
❌ INCORRECT: SELECT * FROM calendar_events
Row Level Security (RLS)
This database uses Row Level Security (RLS) to automatically filter data based on:
- tenant_organization_id: You only see data for your current organization
- system_status: You only see ‘active’ records by default
DO NOT add these filters to your WHERE clause - they are applied automatically:
- ❌
WHERE tenant_organization_id = 1 (unnecessary)
- ❌
WHERE system_status = 'active' (unnecessary)
The RLS policies ensure you only access data you’re authorized to see, making these filters redundant and potentially causing performance issues.
Core Tables Overview
Primary Entity Tables
calendar_events - Master event definitions
calendar_event_instances - Specific occurrences of events
calendar_resources - Bookable resources (rooms, equipment)
calendar_resource_bookings - Resource reservations
calendar_conflicts - Scheduling conflicts
calendar_tags - Event categorization
calendar_tag_groups - Tag groupings
Supporting Entity Tables
calendar_attachments - File attachments for events
calendar_event_connections - Links to other PCO modules
calendar_event_resource_requests - Resource booking requests
calendar_event_resource_answers - Answers to booking questions
calendar_event_times - Time blocks within events
calendar_feeds - Calendar feed configurations
calendar_organizations - Organization settings
calendar_people - People associated with events
calendar_report_templates - Report templates
calendar_required_approvals - Approval requirements
calendar_resource_approval_groups - Approval groups
calendar_resource_folders - Resource organization
calendar_resource_questions - Booking questions
calendar_resource_suggestions - Suggested resources
calendar_room_setups - Room configurations
Relationship Tables
calendar_event_resource_answer_relationships - Links answers to related entities
calendar_event_resource_requests_relationships - Links requests to related entities
calendar_events_relationships - Links events to related entities
calendar_event_instances_relationships - Links instances to related entities
calendar_resources_relationships - Links resources to related entities
calendar_resource_bookings_relationships - Links bookings to related entities
Table Definitions
calendar_events
Master event definitions containing the core event information.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_id | VARCHAR(64) | Planning Center event ID |
approval_status | VARCHAR(1) | Status: ‘A’ (Approved), ‘P’ (Pending), ‘R’ (Rejected), NULL (No approval needed) |
created_at | TIMESTAMP | When event was created |
description | TEXT | Full event description |
featured | BOOLEAN | Whether event is featured/highlighted |
image_url | VARCHAR(2048) | Event image URL |
name | TEXT | Event name/title |
percent_approved | INTEGER | Percentage of approvals received |
percent_rejected | INTEGER | Percentage of rejections received |
registration_url | VARCHAR(2048) | External registration link |
summary | TEXT | Brief event summary |
updated_at | TIMESTAMP | Last update time |
visible_in_church_center | BOOLEAN | Public visibility flag |
owner_id | VARCHAR(64) | Event owner/creator ID |
feed_id | VARCHAR(64) | Associated calendar feed |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status: ‘active’, ‘transferring’, ‘stale’ |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_event_instances
Specific occurrences of events, handling both one-time and recurring events.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_instance_id | VARCHAR(64) | Planning Center instance ID |
all_day_event | BOOLEAN | Whether this is an all-day event |
church_center_url | VARCHAR(2048) | Public URL for this instance |
compact_recurrence_description | TEXT | Short recurrence description |
created_at | TIMESTAMP | Instance creation time |
ends_at | TIMESTAMP | Event end time |
location | TEXT | Event location/venue |
published_ends_at | TIMESTAMP | Published end time (may differ from actual) |
published_starts_at | TIMESTAMP | Published start time |
recurrence | TEXT | Recurrence rule (iCal RRULE format) |
recurrence_description | TEXT | Human-readable recurrence |
starts_at | TIMESTAMP | Event start time |
updated_at | TIMESTAMP | Last update time |
event_id | VARCHAR(64) | Parent event ID |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_resources
Bookable resources including rooms, equipment, and other facilities.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_id | VARCHAR(64) | Planning Center resource ID |
created_at | TIMESTAMP | Resource creation time |
description | TEXT | Resource description |
expires_at | TIMESTAMP | Expiration date (for leased/rented items) |
home_location | TEXT | Default storage location |
image_url | VARCHAR(2048) | Resource image |
image_thumb_url | VARCHAR(2048) | Thumbnail image |
kind | TEXT | Resource type: ‘Room’, ‘Equipment’, ‘Resource’ |
name | TEXT | Resource name |
path_name | TEXT | Hierarchical path (Building/Floor/Room) |
quantity | INTEGER | Available quantity/capacity |
serial_number | TEXT | Serial number (for equipment) |
updated_at | TIMESTAMP | Last update time |
resource_folder | VARCHAR(64) | Parent folder ID |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_resource_bookings
Reservations linking resources to specific events and times.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_booking_id | VARCHAR(64) | Planning Center booking ID |
created_at | TIMESTAMP | Booking creation time |
ends_at | TIMESTAMP | Booking end time |
quantity | INTEGER | Quantity booked |
starts_at | TIMESTAMP | Booking start time |
updated_at | TIMESTAMP | Last update time |
event_id | VARCHAR(64) | Associated event (direct reference for performance) |
event_instance_id | VARCHAR(64) | Associated event instance (direct reference) |
event_resource_request_id | VARCHAR(64) | Original request ID (direct reference) |
resource_id | VARCHAR(64) | Booked resource (direct reference) |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_conflicts
Detected scheduling conflicts between events or resources.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
conflict_id | VARCHAR(64) | Planning Center conflict ID |
created_at | TIMESTAMP | When conflict was detected |
resolved_at | TIMESTAMP | When conflict was resolved |
note | TEXT | Conflict notes/resolution |
resource_booking_id | VARCHAR(64) | First booking in conflict |
conflicting_resource_booking_id | VARCHAR(64) | Second booking in conflict |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Event categorization labels for organizing and filtering.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
tag_id | VARCHAR(64) | Planning Center tag ID |
created_at | TIMESTAMP | Tag creation time |
name | TEXT | Tag name |
position | INTEGER | Display order |
updated_at | TIMESTAMP | Last update time |
tag_group_id | VARCHAR(64) | Parent tag group |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_tag_groups
Groupings for tags to organize them by ministry, event type, etc.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
tag_group_id | VARCHAR(64) | Planning Center tag group ID |
created_at | TIMESTAMP | Group creation time |
name | TEXT | Group name |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_attachments
File attachments associated with events.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
attachment_id | VARCHAR(64) | Planning Center attachment ID |
content_type | TEXT | MIME type of file |
created_at | TIMESTAMP | Attachment creation time |
description | TEXT | Attachment description |
file_size | INTEGER | File size in bytes |
name | TEXT | File name |
updated_at | TIMESTAMP | Last update time |
url | TEXT | Download URL |
event_id | VARCHAR(64) | Associated event |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_event_connections
Links between calendar events and other Planning Center modules.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_connection_id | VARCHAR(64) | Planning Center connection ID |
connected_to_id | VARCHAR(64) | ID of connected entity |
connected_to_name | TEXT | Name of connected entity |
connected_to_type | VARCHAR(50) | Type of connected entity |
connected_to_url | VARCHAR(2048) | URL to connected entity |
product_name | VARCHAR(50) | PCO product (services, groups, etc.) |
event_id | VARCHAR(64) | Associated event |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_event_times
Specific time blocks within event instances (e.g., “Doors Open”, “Main Service”).
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_time_id | VARCHAR(64) | Planning Center event time ID |
ends_at | TIMESTAMP | Time block end |
name | TEXT | Time block name |
starts_at | TIMESTAMP | Time block start |
visible_on_kiosks | BOOLEAN | Show on check-in kiosks |
visible_on_widget_and_ical | BOOLEAN | Show in public widgets/calendars |
event_id | VARCHAR(64) | Associated event |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_room_setups
Predefined room configurations with layout diagrams.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
room_setup_id | VARCHAR(64) | Planning Center setup ID |
created_at | TIMESTAMP | Setup creation time |
description | TEXT | Setup description |
diagram_thumbnail_url | VARCHAR(2048) | Diagram thumbnail |
diagram_url | VARCHAR(2048) | Setup diagram image |
name | TEXT | Setup name |
updated_at | TIMESTAMP | Last update time |
associated_room_setup_id | VARCHAR(64) | Associated room setup (for variants) |
containing_resource_id | VARCHAR(64) | Room resource containing this setup |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_event_resource_requests
Resource requests for events, tracking booking requirements.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_resource_request_id | VARCHAR(64) | Planning Center request ID |
approval_sent | BOOLEAN | Whether approval request was sent |
approval_status | VARCHAR(50) | Approval status |
created_at | TIMESTAMP | Request creation time |
note | TEXT | Request notes |
quantity | INTEGER | Quantity requested |
room_setup_id | VARCHAR(64) | Requested room setup |
updated_at | TIMESTAMP | Last update time |
created_by_id | VARCHAR(64) | Person who created request |
event_id | VARCHAR(64) | Associated event |
resource_id | VARCHAR(64) | Requested resource |
updated_by_id | VARCHAR(64) | Person who last updated |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_event_resource_answers
Answers to resource booking questions.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_resource_answer_id | VARCHAR(64) | Planning Center answer ID |
answer | JSONB | The answer provided (string or array of strings depending on multiple_select) |
question | JSONB | Embedded question details (question, choices, kind, multiple_select, optional, position) |
created_at | TIMESTAMP | Answer creation time |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Note: Relationships (created_by, updated_by, resource_question, event_resource_request) are stored in the calendar_event_resource_answer_relationships table following the golden rule pattern.
calendar_feeds
Calendar feed configurations for importing and syncing events.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
feed_id | VARCHAR(64) | Planning Center feed ID |
can_delete | BOOLEAN | Whether feed can be deleted |
default_church_center_visibility | VARCHAR(50) | Default visibility for imported events |
feed_type | VARCHAR(50) | Type of feed (ical, planning_center) |
imported_at | TIMESTAMP | Last import time |
name | TEXT | Feed name |
source_id | VARCHAR(64) | Source identifier |
event_owner_id | VARCHAR(64) | Default owner for imported events |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_organizations
Organization-wide calendar settings.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
organization_id | VARCHAR(64) | Planning Center organization ID |
date_format | VARCHAR(255) | Date display format |
name | TEXT | Organization name |
time_zone | VARCHAR(255) | Default timezone |
twenty_four_hour_time | BOOLEAN | Use 24-hour time format |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_people
People with calendar permissions and access.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
person_id | VARCHAR(64) | Planning Center person ID |
avatar_url | VARCHAR(2048) | Profile image URL |
can_edit_people | BOOLEAN | Can edit people permissions |
can_edit_resources | BOOLEAN | Can edit resources |
can_edit_rooms | BOOLEAN | Can edit rooms |
child | BOOLEAN | Is a child account |
created_at | TIMESTAMP | Person creation time |
event_permissions_type | VARCHAR(50) | Event permission level |
first_name | VARCHAR(255) | First name |
gender | VARCHAR(10) | Gender |
has_access | BOOLEAN | Has calendar access |
last_name | VARCHAR(255) | Last name |
middle_name | VARCHAR(255) | Middle name |
name | VARCHAR(255) | Full name |
name_prefix | VARCHAR(10) | Name prefix (Mr., Dr., etc.) |
name_suffix | VARCHAR(10) | Name suffix (Jr., III, etc.) |
pending_request_count | INTEGER | Number of pending approval requests |
people_permissions_type | TEXT | People permission level |
permissions | INTEGER | Permission bitmask |
resolves_conflicts | BOOLEAN | Can resolve booking conflicts |
resources_permissions_type | TEXT | Resource permission level |
room_permissions_type | TEXT | Room permission level |
site_administrator | BOOLEAN | Is site administrator |
status | TEXT | Account status |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_report_templates
Report templates for calendar data.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
report_template_id | VARCHAR(64) | Planning Center template ID |
body | TEXT | Template body/content |
created_at | TIMESTAMP | Template creation time |
description | TEXT | Template description |
title | TEXT | Template title |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_required_approvals
Approval requirements for resource bookings.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
required_approval_id | VARCHAR(64) | Planning Center approval ID |
resource_approval_group_id | VARCHAR(64) | Approval group responsible |
resource_id | VARCHAR(64) | Resource requiring approval |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_resource_approval_groups
Groups responsible for approving resource bookings.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_approval_group_id | VARCHAR(64) | Planning Center group ID |
created_at | TIMESTAMP | Group creation time |
name | TEXT | Group name |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_resource_folders
Hierarchical organization of resources.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_folder_id | VARCHAR(64) | Planning Center folder ID |
ancestry | TEXT | Hierarchical path (parent/child/grandchild) |
created_at | TIMESTAMP | Folder creation time |
kind | TEXT | Folder type |
name | TEXT | Folder name |
path_name | TEXT | Full path name |
updated_at | TIMESTAMP | Last update time |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_resource_questions
Booking questions for specific resources.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_question_id | VARCHAR(64) | Planning Center question ID |
choices | TEXT | Available choices (for select fields) |
created_at | TIMESTAMP | Question creation time |
description | TEXT | Question description/help text |
kind | TEXT | Question type (text, select, etc.) |
multiple_select | BOOLEAN | Allow multiple selections |
optional | BOOLEAN | Is answer optional |
position | INTEGER | Display order |
question | TEXT | Question text |
updated_at | TIMESTAMP | Last update time |
resource_id | VARCHAR(64) | Associated resource |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
calendar_resource_suggestions
Suggested resources for room setups.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_suggestion_id | VARCHAR(64) | Planning Center suggestion ID |
created_at | TIMESTAMP | Suggestion creation time |
quantity | INTEGER | Suggested quantity |
updated_at | TIMESTAMP | Last update time |
resource_id | VARCHAR(64) | Suggested resource |
room_setup_id | VARCHAR(64) | Associated room setup |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Relationship Tables
calendar_event_resource_answer_relationships
Links event resource answers to related entities (created_by, updated_by, resource_question, event_resource_request).
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_resource_answer_id | VARCHAR(64) | Parent answer ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Common relationship types:
Person (created_by) - Links to calendar_people (who created the answer)
Person (updated_by) - Links to calendar_people (who last updated the answer)
ResourceQuestion - Links to calendar_resource_questions
EventResourceRequest - Links to calendar_event_resource_requests
calendar_event_resource_requests_relationships
Links resource requests to answers and bookings.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_resource_request_id | VARCHAR(64) | Parent request ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Common relationship types:
ResourceBooking - Links to calendar_resource_bookings
EventResourceAnswer - Links to calendar_event_resource_answers
calendar_events_relationships
Links events to tags, attachments, and other related entities.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_id | VARCHAR(64) | Parent event ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Common relationship types:
Tag - Links to calendar_tags
Attachment - Links to calendar_attachments
Owner - Links to calendar_people
calendar_event_instances_relationships
Links event instances to event times, resource bookings, and tags.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
event_instance_id | VARCHAR(64) | Parent instance ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Common relationship types:
EventTime - Links to calendar_event_times
ResourceBooking - Links to calendar_resource_bookings
Tag - Links to calendar_tags
calendar_resources_relationships
Links resources to approval groups, questions, and room setups.
| Column | Type | Description |
|---|
id | UUID | Internal unique identifier |
resource_id | VARCHAR(64) | Parent resource ID |
relationship_type | VARCHAR(50) | Type of relationship |
relationship_id | VARCHAR(64) | ID of related entity |
tenant_organization_id | INTEGER | Organization identifier |
system_status | VARCHAR(50) | Data status |
system_created_at | TIMESTAMP | When record was created in Parable |
system_updated_at | TIMESTAMP | When record was last updated in Parable |
Common relationship types:
ResourceApprovalGroup - Links to calendar_resource_approval_groups
ResourceQuestion - Links to calendar_resource_questions
RoomSetup - Links to calendar_room_setups
System Fields
All tables include these system fields for data management:
tenant_organization_id - Multi-tenant organization identifier
system_status - Data lifecycle status:
transferring - Being imported from Planning Center
active - Current active data
stale - Marked for removal
system_created_at - When record was created in Parable
system_updated_at - When record was last updated in Parable
Common Query Patterns
-- CORRECT: Schema prefix included, no manual RLS filters
SELECT
e.*,
STRING_AGG(t.name, ', ') as tags
FROM planning_center.calendar_events e
LEFT JOIN planning_center.calendar_events_relationships er
ON e.event_id = er.event_id
AND er.relationship_type = 'Tag'
LEFT JOIN planning_center.calendar_tags t
ON er.relationship_id = t.tag_id
GROUP BY e.id, e.event_id;
Finding Available Resources
SELECT r.*
FROM planning_center.calendar_resources r
WHERE NOT EXISTS (
SELECT 1
FROM planning_center.calendar_resource_bookings rb
WHERE rb.resource_id = r.resource_id
AND rb.starts_at < '2024-01-15 14:00:00'
AND rb.ends_at > '2024-01-15 12:00:00'
);
Detecting Booking Conflicts
SELECT
rb1.resource_booking_id as booking1,
rb2.resource_booking_id as booking2,
r.name as resource_name
FROM planning_center.calendar_resource_bookings rb1
JOIN planning_center.calendar_resource_bookings rb2
ON rb1.resource_id = rb2.resource_id
AND rb1.resource_booking_id < rb2.resource_booking_id
AND rb1.starts_at < rb2.ends_at
AND rb1.ends_at > rb2.starts_at
JOIN planning_center.calendar_resources r
ON rb1.resource_id = r.resource_id
;
Today’s Schedule
SELECT
e.name as event_name,
ei.starts_at,
ei.ends_at,
ei.location
FROM planning_center.calendar_events e
JOIN planning_center.calendar_event_instances ei
ON e.event_id = ei.event_id
AND (
DATE(ei.starts_at) = CURRENT_DATE
OR (ei.all_day_event = true
AND DATE(ei.starts_at) <= CURRENT_DATE
AND DATE(ei.ends_at) >= CURRENT_DATE)
)
ORDER BY ei.starts_at;
Data Integrity Rules
- Schema Qualification: Always use
planning_center. prefix for all table references
- Row Level Security: RLS automatically handles multi-tenancy and status filtering - do not add manual filters
- Monetary Values: Resource fee and cost columns are stored in cents - divide by 100.0 for display
- Time Windows: Use
starts_at/ends_at comparisons and the all_day_event flag rather than relying on system_status
- Direct ID Columns:
calendar_resource_bookings and related tables expose direct IDs for performance-sensitive joins
Common Mistakes to Avoid
-
Missing Schema Prefix
- ❌
FROM calendar_events
- ✅
FROM planning_center.calendar_events
-
Adding Redundant RLS Filters
- ❌
WHERE tenant_organization_id = 1 AND system_status = 'active'
- ✅ Trust RLS to handle this automatically
-
Joining Without Schema
- ❌
JOIN calendar_resource_bookings rb ON ...
- ✅
JOIN planning_center.calendar_resource_bookings rb ON ...
-
Misreporting Fees
- ❌
SELECT resource_fee_cents as resource_fee
- ✅
SELECT resource_fee_cents / 100.0 as resource_fee
-
Indexes: All tables have optimized indexes on:
- Primary keys and entity IDs
- Join columns and foreign keys
- Date columns for time-based queries
-
Query Optimization:
- Always use the
planning_center. schema prefix
- RLS handles tenant and status filtering automatically
- Filter by approval or conflict flags when relevant
- Consider CTEs for complex hierarchical queries
- Use direct ID columns when available instead of relationship tables
Data Types and Conventions
Approval Statuses
A - Approved
P - Pending approval
R - Rejected
NULL - No approval required
Resource Types (kind)
Room - Physical spaces
Equipment - Movable items
Resource - Other bookable items
All-Day Events
all_day_event = true indicates full-day events
- Check date portions of
starts_at and ends_at
- May span multiple days
Recurrence Patterns
- Stored in iCal RRULE format in
recurrence field
- Human-readable in
recurrence_description
- Each occurrence is a separate event_instance
Next Steps