Comprehensive documentation of the SkySpy database schema, including all models, relationships, indexes, and performance considerations.
SkySpy uses PostgreSQL as its primary database engine for production deployments, with SQLite supported for development and lightweight installations. The database schema is managed through Django's ORM and migrations system.
Aspect Details π Primary Database PostgreSQL 14+ π¦ Development Database SQLite (optional) π§ ORM Django 5.x π Connection Pooling CONN_MAX_AGE=60π Schema Management Django Migrations
Python
# Production (PostgreSQL)
DATABASE_URL=postgresql://user:password@host:5432/adsb
# Development (SQLite)
DATABASE_URL=sqlite:///db.sqlite3
erDiagram
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
%% CORE AIRCRAFT TRACKING
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
AircraftSighting ||--o{ AircraftSession : "belongs to"
AircraftSession ||--o| SessionTrackingQuality : "has quality metrics"
AircraftSession ||--o{ PersonalRecord : "sets"
AircraftSession ||--o{ RareSighting : "triggers"
AircraftInfo ||--o{ AirframeSourceData : "has source data"
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
%% USER & AUTHENTICATION
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
User ||--o| SkyspyUser : "has profile"
User ||--o{ UserRole : "has roles"
Role ||--o{ UserRole : "assigned to"
Role ||--o{ OIDCClaimMapping : "mapped from"
User ||--o{ APIKey : "owns"
User ||--o{ AircraftFavorite : "favorites"
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
%% ALERTS & NOTIFICATIONS
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
AlertRule ||--o{ AlertHistory : "triggers"
AlertRule ||--o{ AlertSubscription : "has subscribers"
AlertRule ||--o{ AlertAggregate : "aggregates"
AlertRule }o--o{ NotificationChannel : "sends to"
User ||--o{ AlertRule : "owns"
NotificationChannel ||--o{ NotificationLog : "logs"
NotificationChannel ||--o{ UserNotificationPreference : "preferences"
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
%% SAFETY & EVENTS
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
SafetyEvent }o--|| AircraftSession : "involves"
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
%% CANNONBALL MODE
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
CannonballSession ||--o{ CannonballPattern : "detects"
CannonballSession ||--o{ CannonballAlert : "generates"
CannonballKnownAircraft ||--o{ CannonballSession : "triggers"
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
%% AVIATION DATA
%% βββββββββββββββββββββββββββββββββββββββββββββββββββ
CachedAirport }o--o{ CachedPirep : "reports near"
AirspaceAdvisory }o--o{ AirspaceBoundary : "within"
The database models are organized into the following domain groups:
Domain π Tables Purpose βοΈ Aircraft Tracking 4 Position tracking, sessions, airframe data π Authentication 6 Users, roles, API keys, OIDC π Alerts 4 Rules, history, subscriptions, aggregates π¨ Notifications 5 Channels, templates, logs, preferences β οΈ Safety 1 TCAS events, emergencies πΊοΈ Aviation Data 6 Airports, NOTAMs, airspace, PIREPs ποΈ Audio 1 Radio transmissions, transcriptions π‘ Antenna 1 Performance snapshots β Engagement 2 Favorites, quality tracking π Gamification 9 Personal records, streaks, stats π Cannonball 5 LE detection, patterns, alerts
π AircraftSighting - Individual position reports from ADS-B receiversProperty Value Table Name aircraft_sightingsPrimary Key id (AutoField)Record Count High volume (millions+) Update Frequency Real-time (~1/sec per aircraft)
Field Type βͺ Null Description idπ’ AutoField β Primary key timestampπ
DateTimeField β Position report time (auto-generated) icao_hexπ€ CharField(10) β Mode S transponder code (e.g., "A12345") callsignπ€ CharField(10) β
Flight callsign (e.g., "UAL123") squawkπ€ CharField(4) β
Transponder squawk code latitudeπ’ FloatField β
WGS84 latitude longitudeπ’ FloatField β
WGS84 longitude altitude_baroπ’ IntegerField β
Barometric altitude in feet altitude_geomπ’ IntegerField β
Geometric (GPS) altitude in feet ground_speedπ’ FloatField β
Ground speed in knots trackπ’ FloatField β
Track heading in degrees (0-360) vertical_rateπ’ IntegerField β
Vertical rate in ft/min distance_nmπ’ FloatField β
Distance from receiver in nautical miles rssiπ’ FloatField β
Received signal strength indicator (dBm) categoryπ€ CharField(4) β
ADS-B emitter category aircraft_typeπ€ CharField(10) β
ICAO aircraft type designator is_militaryβ BooleanField β Military aircraft flag is_emergencyβ BooleanField β Emergency squawk active sourceπ€ CharField(10) β Data source (default: "1090")
graph LR
subgraph "Index Strategy"
A["idx_sightings_icao_time"] --> B["(icao_hex, timestamp)"]
C["idx_sighting_timestamp_desc"] --> D["timestamp DESC"]
E["idx_sighting_distance"] --> F["distance_nm WHERE NOT NULL"]
G["idx_sighting_military"] --> H["is_military WHERE TRUE"]
I["idx_sighting_rssi"] --> J["rssi WHERE NOT NULL"]
end Index Name Columns Type idx_sightings_icao_time(icao_hex, timestamp)Composite idx_sighting_timestamp_desctimestamp DESCDescending (PostgreSQL) idx_sighting_distancedistance_nmPartial (WHERE NOT NULL) idx_sighting_icao_timestamp(icao_hex, timestamp DESC)Composite idx_sighting_militaryis_militaryPartial (WHERE TRUE) idx_sighting_rssirssiPartial (WHERE NOT NULL) idx_sighting_tracktrackPartial (WHERE NOT NULL)
π AircraftSession - Continuous tracking session for an aircraft within rangeProperty Value Table Name aircraft_sessionsPrimary Key id (AutoField)Record Count Medium volume (thousands/day) Update Frequency On position update
Field Type βͺ Null Description idπ’ AutoField β Primary key icao_hexπ€ CharField(10) β Mode S transponder code callsignπ€ CharField(10) β
Last seen callsign first_seenπ
DateTimeField β Session start time last_seenπ
DateTimeField β Last position update total_positionsπ’ IntegerField β Position count in session min_altitudeπ’ IntegerField β
Minimum altitude observed max_altitudeπ’ IntegerField β
Maximum altitude observed min_distance_nmπ’ FloatField β
Closest approach max_distance_nmπ’ FloatField β
Maximum distance max_vertical_rateπ’ IntegerField β
Maximum vertical rate min_rssiπ’ FloatField β
Weakest signal max_rssiπ’ FloatField β
Strongest signal is_militaryβ BooleanField β Military aircraft flag categoryπ€ CharField(4) β
ADS-B emitter category aircraft_typeπ€ CharField(10) β
ICAO aircraft type
Index Name Columns Type idx_sessions_last_seen_icao(last_seen, icao_hex)Composite idx_session_last_seenlast_seen DESCDescending idx_session_icao_lastseen(icao_hex, last_seen DESC)Composite
π©οΈ AircraftInfo - Cached aircraft information including registration, operator, and photosProperty Value Table Name aircraft_infoPrimary Key id (AutoField)Unique Constraint icao_hexRecord Count Tens of thousands
Field Type βͺ Null Description idπ’ AutoField β Primary key icao_hexπ€ CharField(10) β Mode S transponder code (unique) registrationπ€ CharField(20) β
Aircraft registration (e.g., "N12345") sourceπ€ CharField(50) β
Data source type_codeπ€ CharField(10) β
ICAO type designator type_nameπ€ CharField(100) β
Full aircraft type name manufacturerπ€ CharField(100) β
Aircraft manufacturer modelπ€ CharField(100) β
Aircraft model serial_numberπ€ CharField(50) β
Manufacturer serial number year_builtπ’ IntegerField β
Year of manufacture first_flight_dateπ€ CharField(20) β
First flight date delivery_dateπ€ CharField(20) β
Delivery date airframe_hoursπ’ IntegerField β
Total airframe hours operatorπ€ CharField(100) β
Current operator name operator_icaoπ€ CharField(4) β
Operator ICAO code operator_callsignπ€ CharField(20) β
Operator radio callsign ownerπ€ CharField(200) β
Registered owner cityπ€ CharField(100) β
Registration city stateπ€ CharField(10) β
Registration state is_interestingβ BooleanField β Interesting aircraft flag is_piaβ BooleanField β Privacy ICAO Address is_laddβ BooleanField β Limiting Aircraft Data Displayed countryπ€ CharField(100) β
Registration country country_codeπ€ CharField(3) β
ISO country code categoryπ€ CharField(20) β
Aircraft category is_militaryβ BooleanField β Military aircraft flag photo_urlπ€ CharField(500) β
Full-size photo URL photo_thumbnail_urlπ€ CharField(500) β
Thumbnail URL photo_photographerπ€ CharField(100) β
Photographer name photo_sourceπ€ CharField(50) β
Photo source photo_page_linkπ€ CharField(500) β
Photo page link photo_local_pathπ€ CharField(500) β
Local cached photo path photo_thumbnail_local_pathπ€ CharField(500) β
Local thumbnail path extra_dataπ¦ JSONField β
Additional data as JSON created_atπ
DateTimeField β Record creation time updated_atπ
DateTimeField β Last update time fetch_failedβ BooleanField β Data fetch failed flag
Index Name Columns Type idx_aircraft_info_regregistrationSingle idx_aircraft_info_operatoroperator_icaoSingle
π AirframeSourceData - Raw airframe data from each data source preserved separatelyProperty Value Table Name airframe_source_dataPrimary Key id (AutoField)Unique Constraint (aircraft_info, source)
Field Type βͺ Null Description idπ’ AutoField β Primary key aircraft_info_idπ ForeignKey β Reference to AircraftInfo sourceπ€ CharField(20) β Data source identifier raw_dataπ¦ JSONField β Complete raw data as JSON registrationπ€ CharField(20) β
Extracted registration type_codeπ€ CharField(10) β
Extracted type code type_nameπ€ CharField(100) β
Extracted type name manufacturerπ€ CharField(100) β
Extracted manufacturer modelπ€ CharField(100) β
Extracted model serial_numberπ€ CharField(50) β
Extracted serial number year_builtπ’ IntegerField β
Extracted year operatorπ€ CharField(100) β
Extracted operator operator_icaoπ€ CharField(4) β
Extracted operator ICAO ownerπ€ CharField(200) β
Extracted owner countryπ€ CharField(100) β
Extracted country cityπ€ CharField(100) β
Extracted city stateπ€ CharField(10) β
Extracted state categoryπ€ CharField(20) β
Extracted category is_militaryβ BooleanField β Military flag is_interestingβ BooleanField β Interesting flag is_piaβ BooleanField β PIA flag is_laddβ BooleanField β LADD flag fetched_atπ
DateTimeField β Data fetch time updated_atπ
DateTimeField β Last update time
Source Description faaFAA Registry adsbxADS-B Exchange tar1090tar1090-db openskyOpenSky Network hexdbHexDB API adsbloladsb.lol API planespottersPlanespotters API
π€ SkyspyUser - Extended user profile with OIDC integration and preferencesProperty Value Table Name skyspy_usersPrimary Key id (AutoField)Relation OneToOne with Django User
Field Type βͺ Null Description idπ’ AutoField β Primary key user_idπ OneToOneField β Reference to Django User auth_providerπ€ CharField(20) β Authentication provider (local/oidc) oidc_subjectπ€ CharField(255) β
OIDC subject identifier (unique) oidc_issuerπ€ CharField(500) β
OIDC issuer URL oidc_claimsπ¦ JSONField β
Cached OIDC claims display_nameπ€ CharField(100) β
Display name avatar_urlπ URLField β
Avatar URL last_activeπ
DateTimeField β
Last activity timestamp last_login_ipπ GenericIPAddressField β
Last login IP preferencesπ¦ JSONField β User preferences JSON created_atπ
DateTimeField β Creation timestamp updated_atπ
DateTimeField β Last update
π Role - Custom role with permission arraysProperty Value Table Name rolesPrimary Key id (AutoField)Unique Constraint name
Field Type βͺ Null Description idπ’ AutoField β Primary key nameπ€ CharField(50) β Role name (unique) display_nameπ€ CharField(100) β Display name descriptionπ TextField β
Role description permissionsπ¦ JSONField β Permission array is_systemβ BooleanField β System role flag priorityπ’ IntegerField β Display priority created_atπ
DateTimeField β Creation timestamp updated_atπ
DateTimeField β Last update
Role Priority Description ποΈ viewer 10 Read-only access βοΈ operator 20 Create/manage own alerts π analyst 30 Export and transcription access π§ admin 40 Full feature access π superadmin 100 All permissions
π UserRole - User-to-role assignment with optional expirationProperty Value Table Name user_rolesPrimary Key id (AutoField)Unique Constraint (user, role)
Field Type βͺ Null Description idπ’ AutoField β Primary key user_idπ ForeignKey β Reference to User role_idπ ForeignKey β Reference to Role expires_atπ
DateTimeField β
Expiration time assigned_by_idπ ForeignKey β
Assigning user created_atπ
DateTimeField β Assignment time
Index Name Columns idx_user_role_expiry(user, expires_at)
π APIKey - Programmatic access keys with scope restrictionsProperty Value Table Name api_keysPrimary Key id (AutoField)Unique Constraint key_hash
Field Type βͺ Null Description idπ’ AutoField β Primary key user_idπ ForeignKey β Reference to User nameπ€ CharField(100) β Key name key_hashπ€ CharField(64) β SHA-256 hash (unique) key_prefixπ€ CharField(16) β First 10 characters scopesπ¦ JSONField β Permission scopes is_activeβ BooleanField β Active status expires_atπ
DateTimeField β
Expiration time last_used_atπ
DateTimeField β
Last usage time last_used_ipπ GenericIPAddressField β
Last usage IP created_atπ
DateTimeField β Creation time
πͺ FeatureAccess - Per-feature public/private access configurationProperty Value Table Name feature_accessPrimary Key feature (CharField)
Field Type βͺ Null Description featureπ€ CharField(30) β Feature ID (primary key) read_accessπ€ CharField(20) β Read access level write_accessπ€ CharField(20) β Write access level is_enabledβ BooleanField β Feature enabled flag settingsπ¦ JSONField β Feature-specific settings updated_atπ
DateTimeField β Last update updated_by_idπ ForeignKey β
Last updater
Level Description π public No authentication required π authenticated Any logged-in user π permission Specific permission required
πΊοΈ OIDCClaimMapping - Map OIDC claims to roles for automatic role assignmentProperty Value Table Name oidc_claim_mappingsPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key nameπ€ CharField(100) β Mapping name claim_nameπ€ CharField(100) β OIDC claim name match_typeπ€ CharField(20) β Match type (exact/contains/regex) claim_valueπ€ CharField(255) β Value to match role_idπ ForeignKey β Role to assign priorityπ’ IntegerField β Processing priority is_activeβ BooleanField β Active status created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
π AlertRule - User-defined alert rules with complex conditionsProperty Value Table Name alert_rulesPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key nameπ€ CharField(100) β Rule name rule_typeπ€ CharField(30) β
Rule type identifier operatorπ€ CharField(10) β Comparison operator valueπ€ CharField(100) β
Comparison value conditionsπ¦ JSONField β
Complex AND/OR conditions descriptionπ€ CharField(200) β
Rule description enabledβ BooleanField β Enabled status priorityπ€ CharField(20) β Priority level starts_atπ
DateTimeField β
Start time expires_atπ
DateTimeField β
Expiration time api_urlπ€ CharField(500) β
Webhook URL cooldown_minutesπ’ IntegerField β Cooldown period last_triggeredπ
DateTimeField β
Last trigger time use_global_notificationsβ BooleanField β Use global config owner_idπ ForeignKey β
Rule owner visibilityπ€ CharField(20) β Visibility level is_systemβ BooleanField β System rule flag is_sharedβ BooleanField β Legacy shared flag suppression_windowsπ¦ JSONField β Suppression windows created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
Operator Symbol Description eq=Equals neq!=Not Equals lt\<Less Than le\<=Less Than or Equal gt\>Greater Than ge\>=Greater Than or Equal contains*...*Contains startswith^...Starts With endswith...$Ends With regex/.../Regex Match
Index Name Columns idx_alert_rules_type(rule_type, enabled)idx_alert_rules_vis(visibility, enabled)idx_alert_rules_owner(owner, enabled)
π AlertHistory - History of triggered alertsProperty Value Table Name alert_historyPrimary Key id (AutoField)Volume High (depends on rule count)
Field Type βͺ Null Description idπ’ AutoField β Primary key rule_idπ ForeignKey β
Reference to AlertRule rule_nameπ€ CharField(100) β
Rule name at trigger time icao_hexπ€ CharField(10) β
Triggering aircraft callsignπ€ CharField(10) β
Aircraft callsign messageπ TextField β
Alert message priorityπ€ CharField(20) β
Alert priority aircraft_dataπ¦ JSONField β
Aircraft snapshot triggered_atπ
DateTimeField β Trigger timestamp user_idπ ForeignKey β
Rule owner session_keyπ€ CharField(40) β
Anonymous session key acknowledgedβ BooleanField β Acknowledged status acknowledged_by_idπ ForeignKey β
Acknowledging user acknowledged_atπ
DateTimeField β
Acknowledgment time
Index Name Columns idx_alert_hist_user(user, triggered_at)idx_alert_hist_ack(acknowledged, triggered_at)idx_alert_history_triggeredtriggered_at DESC
π¬ AlertSubscription - User subscriptions to shared/public alert rulesProperty Value Table Name alert_subscriptionsUnique Constraints (user, rule), (session_key, rule)
Field Type βͺ Null Description idπ’ AutoField β Primary key user_idπ ForeignKey β
Subscribing user session_keyπ€ CharField(40) β
Anonymous session key rule_idπ ForeignKey β Subscribed rule notify_on_triggerβ BooleanField β Notification enabled created_atπ
DateTimeField β Subscription time
π AlertAggregate - Aggregated alert statistics for time windowsProperty Value Table Name alert_aggregatesPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key rule_idπ ForeignKey β Reference to AlertRule window_startπ
DateTimeField β Window start time window_endπ
DateTimeField β Window end time trigger_countπ’ IntegerField β Number of triggers unique_aircraftπ’ IntegerField β Unique aircraft count sample_aircraftπ¦ JSONField β Sample aircraft list
βοΈ NotificationConfig - Singleton notification configurationProperty Value Table Name notification_configPrimary Key id (always 1)Pattern Singleton
Field Type βͺ Null Description idπ’ AutoField β Primary key (always 1) apprise_urlsπ TextField β Apprise URL configuration cooldown_secondsπ’ IntegerField β Default cooldown enabledβ BooleanField β Global enabled flag updated_atπ
DateTimeField β Last update
π‘ NotificationChannel - Reusable notification channel definitionsProperty Value Table Name notification_channelsPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key nameπ€ CharField(100) β Channel name channel_typeπ€ CharField(30) β Channel type apprise_urlπ TextField β Apprise URL descriptionπ€ CharField(200) β
Description supports_richβ BooleanField β Rich formatting support is_globalβ BooleanField β Global availability owner_idπ ForeignKey β
Channel owner enabledβ BooleanField β Enabled status verifiedβ BooleanField β Verified status last_successπ
DateTimeField β
Last success time last_failureπ
DateTimeField β
Last failure time last_errorπ TextField β
Last error message created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
Type Icon Description discordπ¬ Discord slackπ± Slack pushoverπ² Pushover telegramβοΈ Telegram emailπ§ Email webhookπ Generic Webhook ntfyπ ntfy gotifyπ£ Gotify home_assistantπ Home Assistant twilioπ Twilio SMS customπ§ Custom Apprise URL
π NotificationTemplate - Message templates with variable substitutionProperty Value Table Name notification_templatesUnique Constraint name
Field Type βͺ Null Description idπ’ AutoField β Primary key nameπ€ CharField(100) β Template name (unique) descriptionπ€ CharField(200) β
Description title_templateπ€ CharField(200) β Title template body_templateπ TextField β Body template discord_embedπ¦ JSONField β
Discord embed JSON slack_blocksπ¦ JSONField β
Slack Block Kit JSON event_typeπ€ CharField(30) β
Matching event type priorityπ€ CharField(20) β
Matching priority is_defaultβ BooleanField β Default template flag created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
π NotificationLog - Log of sent notifications with retry trackingProperty Value Table Name notification_logsPrimary Key id (AutoField)Volume High
Field Type βͺ Null Description idπ’ AutoField β Primary key timestampπ
DateTimeField β Log timestamp notification_typeπ€ CharField(50) β
Notification type icao_hexπ€ CharField(10) β
Aircraft ICAO callsignπ€ CharField(10) β
Aircraft callsign messageπ TextField β
Notification message detailsπ¦ JSONField β
Additional details channel_idπ ForeignKey β
Channel reference channel_urlπ TextField β
Actual URL used statusπ€ CharField(20) β Status (pending/sent/failed/retrying) retry_countπ’ IntegerField β Retry attempt count max_retriesπ’ IntegerField β Maximum retries next_retry_atπ
DateTimeField β
Next retry time last_errorπ TextField β
Last error message sent_atπ
DateTimeField β
Send time duration_msπ’ IntegerField β
Send duration
π UserNotificationPreference - Per-user notification preferencesProperty Value Table Name user_notification_preferencesUnique Constraint (user, channel)
Field Type βͺ Null Description idπ’ AutoField β Primary key user_idπ ForeignKey β User reference channel_idπ ForeignKey β Channel reference min_priorityπ€ CharField(20) β Minimum priority event_typesπ¦ JSONField β Event type filter quiet_hours_startβ° TimeField β
Quiet hours start quiet_hours_endβ° TimeField β
Quiet hours end critical_overrides_quietβ BooleanField β Critical override flag timezoneπ€ CharField(50) β User timezone enabledβ BooleanField β Enabled status created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
π¨ SafetyEvent - TCAS conflicts and dangerous flight parametersProperty Value Table Name safety_eventsPrimary Key id (AutoField)Criticality High
Field Type βͺ Null Description idπ’ AutoField β Primary key timestampπ
DateTimeField β Event timestamp event_typeπ€ CharField(50) β Event type severityπ€ CharField(20) β Severity level icao_hexπ€ CharField(10) β Primary aircraft icao_hex_2π€ CharField(10) β
Secondary aircraft callsignπ€ CharField(10) β
Primary callsign callsign_2π€ CharField(10) β
Secondary callsign messageπ TextField β
Event message detailsπ¦ JSONField β
Event details aircraft_snapshotπ¦ JSONField β
Primary telemetry snapshot aircraft_snapshot_2π¦ JSONField β
Secondary telemetry snapshot acknowledgedβ BooleanField β Acknowledged status acknowledged_atπ
DateTimeField β
Acknowledgment time
Type Severity Description tcas_raπ΄ Critical TCAS Resolution Advisory tcas_taπ High TCAS Traffic Advisory extreme_vsπ High Extreme Vertical Speed vs_reversalπ‘ Medium Vertical Speed Reversal proximity_conflictπ΄ Critical Proximity Conflict emergency_squawkπ΄ Critical Emergency Squawk 7500π΄ Critical Squawk 7500 (Hijack) 7600π High Squawk 7600 (Radio Failure) 7700π΄ Critical Squawk 7700 (Emergency)
Index Name Columns idx_safety_events_type_time(event_type, timestamp)idx_safety_event_timestamptimestamp DESC
π« CachedAirport - Cached airport data from Aviation Weather CenterProperty Value Table Name cached_airportsUnique Constraint icao_idRefresh Rate 30 days
Field Type βͺ Null Description idπ’ AutoField β Primary key fetched_atπ
DateTimeField β Fetch timestamp icao_idπ€ CharField(4) β ICAO identifier (unique) nameπ€ CharField(200) β
Airport name latitudeπ’ FloatField β WGS84 latitude longitudeπ’ FloatField β WGS84 longitude elevation_ftπ’ IntegerField β
Field elevation airport_typeπ€ CharField(50) β
Airport type countryπ€ CharField(100) β
Country name regionπ€ CharField(100) β
Region/state source_dataπ¦ JSONField β
Raw API response
π‘ CachedNavaid - Cached navigation aid dataProperty Value Table Name cached_navaidsPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key fetched_atπ
DateTimeField β Fetch timestamp identπ€ CharField(10) β Navaid identifier nameπ€ CharField(100) β
Navaid name navaid_typeπ€ CharField(20) β
Type (VOR, NDB, etc.) latitudeπ’ FloatField β WGS84 latitude longitudeπ’ FloatField β WGS84 longitude frequencyπ’ FloatField β
Frequency (MHz/kHz) channelπ€ CharField(10) β
TACAN channel source_dataπ¦ JSONField β
Raw API response
π CachedNotam - Cached NOTAM and TFR dataProperty Value Table Name cached_notamsUnique Constraint notam_idArchive Support Yes
Field Type βͺ Null Description idπ’ AutoField β Primary key notam_idπ€ CharField(50) β NOTAM identifier (unique) notam_typeπ€ CharField(10) β NOTAM type classificationπ€ CharField(20) β
Classification locationπ€ CharField(10) β ICAO location latitudeπ’ FloatField β
Center latitude longitudeπ’ FloatField β
Center longitude radius_nmπ’ FloatField β
TFR radius floor_ftπ’ IntegerField β
Floor altitude ceiling_ftπ’ IntegerField β
Ceiling altitude effective_startπ
DateTimeField β Start time effective_endπ
DateTimeField β
End time is_permanentβ BooleanField β Permanent flag textπ TextField β NOTAM text raw_textπ TextField β
Raw NOTAM text keywordsπ¦ JSONField β
Extracted keywords geometryπ¦ JSONField β
TFR GeoJSON boundary reasonπ€ CharField(200) β
TFR reason source_dataπ¦ JSONField β
Raw API response fetched_atπ
DateTimeField β Fetch timestamp created_atπ
DateTimeField β Creation time is_archivedβ BooleanField β Archived status archived_atπ
DateTimeField β
Archive time archive_reasonπ€ CharField(50) β
Archive reason
Index Name Columns idx_notam_loc_start(location, effective_start)idx_notam_type_start(notam_type, effective_start)idx_notam_location(latitude, longitude)idx_notam_validity(effective_end, effective_start)idx_notam_archive(is_archived, archived_at)
π€οΈ AirspaceAdvisory - Active airspace advisories (G-AIRMETs, SIGMETs)Property Value Table Name airspace_advisoriesPrimary Key id (AutoField)Refresh Rate Hourly
Field Type βͺ Null Description idπ’ AutoField β Primary key fetched_atπ
DateTimeField β Fetch timestamp advisory_idπ€ CharField(50) β Advisory identifier advisory_typeπ€ CharField(20) β Advisory type hazardπ€ CharField(20) β
Hazard type severityπ€ CharField(20) β
Severity level valid_fromπ
DateTimeField β
Valid from time valid_toπ
DateTimeField β
Valid to time lower_alt_ftπ’ IntegerField β
Lower altitude upper_alt_ftπ’ IntegerField β
Upper altitude regionπ€ CharField(20) β
Geographic region polygonπ¦ JSONField β
GeoJSON polygon raw_textπ TextField β
Raw advisory text source_dataπ¦ JSONField β
Raw API response
π² AirspaceBoundary - Static airspace boundary data (Class B/C/D, MOAs)Property Value Table Name airspace_boundariesPrimary Key id (AutoField)Update Frequency Monthly
Field Type βͺ Null Description idπ’ AutoField β Primary key fetched_atπ
DateTimeField β Fetch timestamp nameπ€ CharField(100) β Airspace name icaoπ€ CharField(4) β
Associated airport airspace_classπ€ CharField(20) β Airspace class floor_ftπ’ IntegerField β Floor altitude ceiling_ftπ’ IntegerField β Ceiling altitude center_latπ’ FloatField β Center latitude center_lonπ’ FloatField β Center longitude radius_nmπ’ FloatField β
Radius (circular) polygonπ¦ JSONField β
GeoJSON polygon controlling_agencyπ€ CharField(100) β
Controlling agency scheduleπ€ CharField(200) β
Operating schedule sourceπ€ CharField(50) β Data source source_idπ€ CharField(100) β
External ID updated_atπ
DateTimeField β Last update
βοΈ CachedPirep - Cached Pilot Reports (PIREPs)Property Value Table Name cached_pirepsUnique Constraint pirep_idRetention 24 hours
Field Type βͺ Null Description idπ’ AutoField β Primary key fetched_atπ
DateTimeField β Fetch timestamp pirep_idπ€ CharField(100) β PIREP identifier (unique) report_typeπ€ CharField(10) β Report type (UA/UUA) latitudeπ’ FloatField β
Location latitude longitudeπ’ FloatField β
Location longitude locationπ€ CharField(50) β
Location string observation_timeπ
DateTimeField β
Observation time flight_levelπ’ IntegerField β
Flight level altitude_ftπ’ IntegerField β
Altitude in feet aircraft_typeπ€ CharField(10) β
Reporting aircraft type turbulence_typeπ€ CharField(20) β
Turbulence intensity turbulence_freqπ€ CharField(20) β
Turbulence frequency turbulence_base_ftπ’ IntegerField β
Turbulence base turbulence_top_ftπ’ IntegerField β
Turbulence top icing_typeπ€ CharField(20) β
Icing intensity icing_intensityπ€ CharField(20) β
Icing type icing_base_ftπ’ IntegerField β
Icing base icing_top_ftπ’ IntegerField β
Icing top sky_coverπ€ CharField(100) β
Sky condition visibility_smπ’ FloatField β
Visibility (SM) weatherπ€ CharField(100) β
Weather phenomena temperature_cπ’ IntegerField β
Temperature wind_dirπ’ IntegerField β
Wind direction wind_speed_ktπ’ IntegerField β
Wind speed raw_textπ TextField β
Raw PIREP text source_dataπ¦ JSONField β
Raw API response is_archivedβ BooleanField β Archived status archived_atπ
DateTimeField β
Archive time archive_reasonπ€ CharField(50) β
Archive reason
π AudioTransmission - Audio transmissions captured for transcriptionProperty Value Table Name audio_transmissionsPrimary Key id (AutoField)Storage S3/Local
Field Type βͺ Null Description idπ’ AutoField β Primary key created_atπ
DateTimeField β Creation timestamp filenameπ€ CharField(255) β Audio filename s3_keyπ€ CharField(500) β
S3 object key s3_urlπ€ CharField(500) β
S3 URL file_size_bytesπ’ IntegerField β
File size duration_secondsπ’ FloatField β
Audio duration formatπ€ CharField(10) β Audio format frequency_mhzπ’ FloatField β
Radio frequency channel_nameπ€ CharField(100) β
Channel name squelch_levelπ’ FloatField β
Squelch level transcription_statusπ€ CharField(20) β Transcription status transcription_queued_atπ
DateTimeField β
Queue time transcription_started_atπ
DateTimeField β
Start time transcription_completed_atπ
DateTimeField β
Completion time transcription_errorπ TextField β
Error message transcriptπ TextField β
Transcription text transcript_confidenceπ’ FloatField β
Confidence score transcript_languageπ€ CharField(10) β
Detected language transcript_segmentsπ¦ JSONField β
Word-level timestamps identified_airframesπ¦ JSONField β
Identified aircraft extra_metadataπ¦ JSONField β
Additional metadata
π AntennaAnalyticsSnapshot - Periodic antenna performance snapshotsProperty Value Table Name antenna_analytics_snapshotsPrimary Key id (AutoField)Snapshot Types scheduled, hourly, daily
Field Type βͺ Null Description idπ’ AutoField β Primary key timestampπ
DateTimeField β Snapshot timestamp snapshot_typeπ€ CharField(20) β Type (scheduled/hourly/daily) window_hoursπ’ FloatField β Time window size max_range_nmπ’ FloatField β
Maximum range avg_range_nmπ’ FloatField β
Average range min_range_nmπ’ FloatField β
Minimum range range_p50_nmπ’ FloatField β
50th percentile range range_p75_nmπ’ FloatField β
75th percentile range range_p90_nmπ’ FloatField β
90th percentile range range_p95_nmπ’ FloatField β
95th percentile range best_rssiπ’ FloatField β
Best signal strength avg_rssiπ’ FloatField β
Average signal strength worst_rssiπ’ FloatField β
Worst signal strength total_positionsπ’ IntegerField β Total position count unique_aircraftπ’ IntegerField β Unique aircraft count positions_per_hourπ’ FloatField β Position rate range_by_directionπ¦ JSONField β Directional range data sectors_with_dataπ’ IntegerField β Sectors with data (0-12) coverage_percentageπ’ FloatField β Coverage percentage estimated_gain_dbπ’ FloatField β
Estimated antenna gain performance_scoreπ’ FloatField β
Performance score (0-100)
β€οΈ AircraftFavorite - User-favorited aircraft trackingProperty Value Table Name aircraft_favoritesUnique Constraints (user, icao_hex), (session_key, icao_hex)
Field Type βͺ Null Description idπ’ AutoField β Primary key user_idπ ForeignKey β
User reference session_keyπ€ CharField(40) β
Anonymous session icao_hexπ€ CharField(10) β Aircraft ICAO registrationπ€ CharField(20) β
Registration callsignπ€ CharField(10) β
Last callsign notesπ TextField β
User notes times_seenπ’ IntegerField β Times seen while favorited last_seen_atπ
DateTimeField β
Last seen time total_tracking_minutesπ’ FloatField β Total tracking time notify_on_detectionβ BooleanField β Notification enabled created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
πΆ SessionTrackingQuality - Extended session quality metricsProperty Value Table Name session_tracking_qualityRelation OneToOne with AircraftSession
Field Type βͺ Null Description idπ’ AutoField β Primary key session_idπ OneToOneField β Session reference expected_positionsπ’ IntegerField β Expected positions actual_positionsπ’ IntegerField β Actual positions completeness_scoreπ’ FloatField β Completeness (0-100) avg_update_rateπ’ FloatField β Positions per minute total_gapsπ’ IntegerField β Number of gaps max_gap_secondsπ’ IntegerField β Longest gap avg_gap_secondsπ’ FloatField β Average gap gap_percentageπ’ FloatField β Gap percentage avg_rssiπ’ FloatField β
Average signal rssi_varianceπ’ FloatField β
Signal variance quality_gradeπ€ CharField(20) β Quality grade calculated_atπ
DateTimeField β Calculation time
π₯ PersonalRecord - All-time personal bestsProperty Value Table Name personal_recordsUnique Constraint record_type
Field Type βͺ Null Description idπ’ AutoField β Primary key record_typeπ€ CharField(50) β Record type (unique) icao_hexπ€ CharField(10) β Record-holding aircraft callsignπ€ CharField(10) β
Callsign aircraft_typeπ€ CharField(10) β
Aircraft type registrationπ€ CharField(20) β
Registration operatorπ€ CharField(100) β
Operator valueπ’ FloatField β Record value session_idπ ForeignKey β
Session reference achieved_atπ
DateTimeField β Achievement time previous_valueπ’ FloatField β
Previous record previous_icao_hexπ€ CharField(10) β
Previous holder previous_achieved_atπ
DateTimeField β
Previous time created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
Record Icon Description max_distanceπ Furthest Aircraft Tracked max_altitudeβ¬οΈ Highest Altitude Aircraft max_speedπ¨ Fastest Aircraft Tracked longest_sessionβ±οΈ Longest Tracking Session most_positionsπ Most Positions for Single Aircraft closest_approachπ― Closest Approach max_vertical_rateπ Fastest Climb Rate max_descent_rateπ Fastest Descent Rate earliest_morningπ
Earliest Morning Sighting latest_nightπ Latest Night Sighting
π
DailyStats - Daily aggregated statisticsProperty Value Table Name daily_statsUnique Constraint date
Field Type βͺ Null Description idπ’ AutoField β Primary key dateπ
DateField β Statistics date (unique) unique_aircraftπ’ IntegerField β Unique aircraft count new_aircraftπ’ IntegerField β First-time sightings total_sessionsπ’ IntegerField β Session count total_positionsπ’ IntegerField β Position count military_countπ’ IntegerField β Military aircraft count max_distance_nmπ’ FloatField β
Maximum distance max_altitudeπ’ IntegerField β
Maximum altitude max_speedπ’ FloatField β
Maximum speed aircraft_typesπ¦ JSONField β Type distribution operatorsπ¦ JSONField β Operator distribution created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
Cannonball Mode provides law enforcement aircraft detection and pattern analysis.
flowchart LR
subgraph Detection
A[Known Aircraft DB] --> B{Match?}
C[Pattern Analysis] --> B
end
subgraph Tracking
B --> D[Cannonball Session]
D --> E[Pattern Detection]
D --> F[Alert Generation]
end
subgraph Analysis
E --> G[Circling]
E --> H[Loitering]
E --> I[Grid Search]
E --> J[Surveillance]
end
π CannonballPattern - Detected flight patterns indicating surveillance activityProperty Value Table Name cannonball_patternsPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key icao_hexπ€ CharField(10) β Aircraft ICAO callsignπ€ CharField(10) β
Callsign pattern_typeπ€ CharField(30) β Pattern type confidenceπ€ CharField(10) β Confidence level confidence_scoreπ’ FloatField β Confidence score (0-1) center_latπ’ FloatField β Pattern center latitude center_lonπ’ FloatField β Pattern center longitude radius_nmπ’ FloatField β
Pattern radius pattern_dataπ¦ JSONField β Additional pattern data position_samplesπ¦ JSONField β Position samples started_atπ
DateTimeField β Pattern start time ended_atπ
DateTimeField β
Pattern end time duration_secondsπ’ IntegerField β Duration detected_atπ
DateTimeField β Detection timestamp session_idπ ForeignKey β
Session reference
Type Icon Description circlingπ Circling loiteringβΈοΈ Loitering grid_searchπ² Grid Search speed_trapπ Speed Trap parallel_highwayπ£οΈ Parallel to Highway surveillanceποΈ General Surveillance pursuitπ Pursuit Pattern
π CannonballSession - Tracking session for potential law enforcement aircraftProperty Value Table Name cannonball_sessionsPrimary Key id (AutoField)
Field Type βͺ Null Description idπ’ AutoField β Primary key icao_hexπ€ CharField(10) β Aircraft ICAO callsignπ€ CharField(10) β
Callsign registrationπ€ CharField(15) β
Registration identification_methodπ€ CharField(20) β How identified identification_reasonπ€ CharField(200) β
Identification reason operator_nameπ€ CharField(100) β
Operator name operator_icaoπ€ CharField(10) β
Operator ICAO aircraft_typeπ€ CharField(50) β
Aircraft type is_activeβ BooleanField β Active status threat_levelπ€ CharField(20) β Threat level urgency_scoreπ’ FloatField β Urgency score (0-100) last_latπ’ FloatField β
Last latitude last_lonπ’ FloatField β
Last longitude last_altitudeπ’ IntegerField β
Last altitude last_ground_speedπ’ IntegerField β
Last ground speed last_trackπ’ IntegerField β
Last track user_idπ ForeignKey β
User reference distance_nmπ’ FloatField β
Distance from user bearingπ’ FloatField β
Bearing from user closing_speed_ktsπ’ FloatField β
Closing speed first_seenπ
DateTimeField β Session start last_seenπ
DateTimeField β Last update session_duration_secondsπ’ IntegerField β Duration pattern_countπ’ IntegerField β Pattern count alert_countπ’ IntegerField β Alert count position_countπ’ IntegerField β Position count metadataπ¦ JSONField β Additional metadata
ποΈ CannonballKnownAircraft - Database of known law enforcement aircraftProperty Value Table Name cannonball_known_aircraftUnique Constraint icao_hex
Field Type βͺ Null Description idπ’ AutoField β Primary key icao_hexπ€ CharField(10) β Aircraft ICAO (unique) registrationπ€ CharField(15) β
Registration aircraft_typeπ€ CharField(50) β
Aircraft type aircraft_modelπ€ CharField(100) β
Aircraft model agency_nameπ€ CharField(200) β Agency name agency_typeπ€ CharField(20) β Agency type agency_stateπ€ CharField(2) β
US state agency_cityπ€ CharField(100) β
City sourceπ€ CharField(20) β Data source source_urlπ URLField β
Source URL verifiedβ BooleanField β Verified status verified_atπ
DateTimeField β
Verification time verified_by_idπ ForeignKey β
Verifying user times_detectedπ’ IntegerField β Detection count last_detectedπ
DateTimeField β
Last detection notesπ TextField β
Notes created_atπ
DateTimeField β Creation time updated_atπ
DateTimeField β Last update
SkySpy uses a comprehensive indexing strategy optimized for common query patterns.
graph TD
subgraph "Query Patterns"
A[Time-Based] --> A1["Recent sightings"]
A --> A2["Session history"]
B[Aircraft Lookups] --> B1["Track by ICAO"]
B --> B2["History queries"]
C[Filtered Queries] --> C1["Military aircraft"]
C --> C2["Distance range"]
C --> C3["Signal strength"]
end
subgraph "Index Types"
D[Composite] --> D1["Multi-column"]
E[Partial] --> E1["Conditional"]
F[Descending] --> F1["Time ordering"]
end
A1 --> F
A2 --> F
B1 --> D
B2 --> D
C1 --> E
C2 --> E
C3 --> E
Tip : Partial indexes in PostgreSQL dramatically reduce index size for sparse boolean columns like is_military (typically less than 5% of traffic).
SQL
-- Most common pattern: Recent sightings ordered by time
CREATE INDEX idx_sighting_timestamp_desc ON aircraft_sightings(timestamp DESC);
CREATE INDEX idx_session_last_seen ON aircraft_sessions(last_seen DESC);
SQL
-- Track history for specific aircraft
CREATE INDEX idx_sighting_icao_timestamp ON aircraft_sightings(icao_hex, timestamp DESC);
CREATE INDEX idx_session_icao_lastseen ON aircraft_sessions(icao_hex, last_seen DESC);
SQL
-- Military aircraft filtering (typically less than 5% of traffic)
CREATE INDEX idx_sighting_military ON aircraft_sightings(is_military) WHERE is_military = TRUE;
-- Distance-based queries (exclude null values)
CREATE INDEX idx_sighting_distance ON aircraft_sightings(distance_nm) WHERE distance_nm IS NOT NULL;
Performance Best Practices
Pattern Recommendation π
Recent sightings Use timestamp__gte with indexed column βοΈ Aircraft history Query by icao_hex first, then filter by time π Distance filtering Use partial index, exclude nulls ποΈ Military aircraft Partial index on boolean flag π Session lookups Use composite (icao_hex, last_seen) index
Python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'CONN_MAX_AGE': 60, # Reuse connections for 60 seconds
}
}
Table Retention Policy π aircraft_sightings 30 days Archive older positions π aircraft_sessions 90 days Keep for history π alert_history 90 days Archive older alerts π¨ notification_logs 30 days Delete after retention β οΈ safety_events 1 year Archive for analysis
Table Retention Policy π©οΈ aircraft_info Indefinite Update on access π« cached_airports 30 days Refresh periodically π cached_notams Active + 7 days Archive expired βοΈ cached_pireps 24 hours Archive after expiry π€οΈ airspace_advisories Active + 24 hours Archive expired
Python
# Mark expired NOTAMs as archived
CachedNotam.objects.filter(
effective_end__lt=timezone.now() - timedelta(days=7),
is_archived=False
).update(
is_archived=True,
archived_at=timezone.now(),
archive_reason='expired'
)
Bash
# Apply all pending migrations
python manage.py migrate
# Show migration status
python manage.py showmigrations
# Create new migration
python manage.py makemigrations skyspy
Important Guidelines
Never edit applied migrations - Create new migrations for changes
Use atomic=False for index creation - Allows CREATE INDEX CONCURRENTLY
Test on copy of production data - Verify performance impact
Backup before major migrations - Enable rollback capability
Python
class Migration(migrations.Migration):
atomic = False # Required for CONCURRENTLY
operations = [
PostgreSQLOnlyRunSQL(
sql="CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_name ON table(column);",
reverse_sql="DROP INDEX CONCURRENTLY IF EXISTS idx_name;",
),
]
For large tables, use the following pattern:
Add new columns as nullable
Backfill data in batches
Add NOT NULL constraint if needed
Create indexes concurrently
Metric β οΈ Warning π΄ Critical Connection count 80% of max 95% of max Query duration (p99) 500ms 2000ms Table bloat 20% 40% Index bloat 30% 50% Disk usage 70% 85%
SQL
-- Active connections
SELECT count(*) FROM pg_stat_activity WHERE state = 'active';
-- Slow queries
SELECT query, calls, mean_time, max_time
FROM pg_stat_statements
ORDER BY mean_time DESC LIMIT 10;
-- Table sizes
SELECT relname, pg_size_pretty(pg_total_relation_size(relid))
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC;
-- Index usage
SELECT indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC;
Bash
# Full database backup
pg_dump -h localhost -U adsb adsb > backup_$(date +%Y%m%d).sql
# Schema-only backup
pg_dump -h localhost -U adsb --schema-only adsb > schema.sql
# Data-only backup
pg_dump -h localhost -U adsb --data-only adsb > data.sql
Configure WAL archiving in PostgreSQL:
ini
archive_mode = on
archive_command = 'cp %p /backup/wal/%f'
Bash
# Restore from backup
psql -h localhost -U adsb adsb < backup.sql
# Restore to specific point in time
pg_restore --target-time="2024-01-15 10:00:00" -d adsb backup.dump
Version Date Changes 0.1.0 2024-01 Initial schema with aircraft tracking 0.2.0 2024-06 Added auth, alerts, notifications 0.3.0 2024-09 Added gamification, cannonball mode 0.4.0 2024-12 Performance indexes, archive support