45 lines
2.0 KiB
SQL
45 lines
2.0 KiB
SQL
-- FR24 External data schema
|
|
-- Phase 2, Step 1: Airport schedule (Yandex.Rasp + OpenSky)
|
|
|
|
CREATE SCHEMA IF NOT EXISTS fr24_ext;
|
|
|
|
-- Airport schedule (merged from Yandex + OpenSky)
|
|
CREATE TABLE IF NOT EXISTS fr24_ext.schedule (
|
|
schedule_id BIGSERIAL PRIMARY KEY,
|
|
flight_date DATE NOT NULL,
|
|
airport_iata CHAR(3) NOT NULL,
|
|
direction VARCHAR(10) NOT NULL CHECK (direction IN ('arrival', 'departure')),
|
|
flight_number VARCHAR(10) NOT NULL,
|
|
airline_iata CHAR(2),
|
|
airline_name VARCHAR(100),
|
|
origin_iata CHAR(3),
|
|
destination_iata CHAR(3),
|
|
aircraft_type VARCHAR(10),
|
|
scheduled_at TIMESTAMPTZ NOT NULL,
|
|
estimated_at TIMESTAMPTZ,
|
|
actual_at TIMESTAMPTZ,
|
|
status VARCHAR(20) DEFAULT 'scheduled'
|
|
CHECK (status IN ('scheduled', 'delayed', 'cancelled', 'departed', 'arrived')),
|
|
icao24 CHAR(6),
|
|
source VARCHAR(20) NOT NULL CHECK (source IN ('yandex', 'opensky', 'merged')),
|
|
fetched_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE (flight_number, airport_iata, scheduled_at, direction)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_schedule_date ON fr24_ext.schedule (flight_date);
|
|
CREATE INDEX IF NOT EXISTS idx_schedule_airport ON fr24_ext.schedule (airport_iata);
|
|
CREATE INDEX IF NOT EXISTS idx_schedule_flight ON fr24_ext.schedule (flight_number);
|
|
CREATE INDEX IF NOT EXISTS idx_schedule_time ON fr24_ext.schedule (scheduled_at);
|
|
CREATE INDEX IF NOT EXISTS idx_schedule_dir ON fr24_ext.schedule (direction);
|
|
CREATE INDEX IF NOT EXISTS idx_schedule_status ON fr24_ext.schedule (status);
|
|
|
|
-- Load state / backfill cursor
|
|
CREATE TABLE IF NOT EXISTS fr24_ext.load_state (
|
|
state_key VARCHAR(50) PRIMARY KEY,
|
|
state_value JSONB NOT NULL,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
COMMENT ON TABLE fr24_ext.schedule IS 'Airport schedule from Yandex.Rasp + OpenSky, T-1 mode';
|
|
COMMENT ON TABLE fr24_ext.load_state IS 'Backfill cursor and load progress tracking';
|