Alpha stage commit
This commit is contained in:
612
app/models.py
Normal file
612
app/models.py
Normal file
@@ -0,0 +1,612 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import BigInteger, Boolean, DateTime, Float, ForeignKey, Integer, String, Text, UniqueConstraint
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.db import Base
|
||||
|
||||
|
||||
def now_utc() -> datetime:
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
|
||||
class Source(Base):
|
||||
__tablename__ = "sources"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
catalog_entry_id: Mapped[Optional[int]] = mapped_column(ForeignKey("source_catalog_entries.id"), nullable=True, index=True)
|
||||
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
kind: Mapped[str] = mapped_column(String(64), nullable=False) # gtfs, osm_geojson, osm_pbf, osm_diff
|
||||
url: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
country: Mapped[Optional[str]] = mapped_column(String(8), nullable=True)
|
||||
license: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||
priority: Mapped[Optional[str]] = mapped_column(String(16), nullable=True, index=True)
|
||||
mode_scope: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
source_basis: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||||
status: Mapped[str] = mapped_column(String(64), default="new", nullable=False)
|
||||
last_error: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
last_run_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
catalog_entry: Mapped[Optional["SourceCatalogEntry"]] = relationship()
|
||||
datasets: Mapped[list["Dataset"]] = relationship(back_populates="source", cascade="all, delete-orphan")
|
||||
update_checks: Mapped[list["SourceUpdateCheck"]] = relationship(back_populates="source", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class SourceCatalogEntry(Base):
|
||||
__tablename__ = "source_catalog_entries"
|
||||
__table_args__ = (UniqueConstraint("catalog_key", name="uq_source_catalog_entry_key"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
catalog_key: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
geography: Mapped[Optional[str]] = mapped_column(String(128), nullable=True, index=True)
|
||||
country_code: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
mode_scope: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
source_name: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
source_category: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
formats_apis: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
availability: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
coverage_notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
geometry_notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
disruptions_closures: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
operator_list_use: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
access_license_notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
priority: Mapped[Optional[str]] = mapped_column(String(32), nullable=True, index=True)
|
||||
source_url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
evidence_url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
next_pipeline_action: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
status: Mapped[str] = mapped_column(String(64), default="backlog", nullable=False, index=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
|
||||
class Dataset(Base):
|
||||
__tablename__ = "datasets"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
source_id: Mapped[int] = mapped_column(ForeignKey("sources.id"), nullable=False, index=True)
|
||||
kind: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
local_path: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
sha256: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||||
status: Mapped[str] = mapped_column(String(64), default="imported", nullable=False)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
source: Mapped[Source] = relationship(back_populates="datasets")
|
||||
|
||||
|
||||
class SourceUpdateCheck(Base):
|
||||
__tablename__ = "source_update_checks"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
source_id: Mapped[int] = mapped_column(ForeignKey("sources.id"), nullable=False, index=True)
|
||||
checked_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="checked", index=True)
|
||||
update_available: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
||||
reason: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
remote_url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
etag: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
last_modified: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
content_length: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||
content_type: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
local_mtime: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
local_size: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||
local_sha256: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
|
||||
active_dataset_id: Mapped[Optional[int]] = mapped_column(ForeignKey("datasets.id"), nullable=True, index=True)
|
||||
active_dataset_sha256: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
|
||||
source: Mapped[Source] = relationship(back_populates="update_checks")
|
||||
active_dataset: Mapped[Optional[Dataset]] = relationship()
|
||||
|
||||
|
||||
class OsmDiffState(Base):
|
||||
__tablename__ = "osm_diff_states"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
source_id: Mapped[int] = mapped_column(ForeignKey("sources.id"), nullable=False, index=True)
|
||||
raw_dataset_id: Mapped[Optional[int]] = mapped_column(ForeignKey("datasets.id"), nullable=True, index=True)
|
||||
updates_url: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
sequence_number: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
|
||||
timestamp: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="active", index=True)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
source: Mapped[Source] = relationship()
|
||||
raw_dataset: Mapped[Optional[Dataset]] = relationship()
|
||||
|
||||
|
||||
class Job(Base):
|
||||
__tablename__ = "jobs"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
kind: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="queued", index=True)
|
||||
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
progress_current: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
||||
progress_total: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
||||
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=0, index=True)
|
||||
requested_action: Mapped[Optional[str]] = mapped_column(String(32), nullable=True, index=True)
|
||||
lease_owner: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, index=True)
|
||||
lease_expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
|
||||
paused_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
result_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
error: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
dismissed_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, index=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
started_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
finished_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
events: Mapped[list["JobEvent"]] = relationship(back_populates="job", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class JobEvent(Base):
|
||||
__tablename__ = "job_events"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
job_id: Mapped[int] = mapped_column(ForeignKey("jobs.id"), nullable=False, index=True)
|
||||
level: Mapped[str] = mapped_column(String(32), nullable=False, default="info", index=True)
|
||||
event_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
||||
message: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
progress_current: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||
progress_total: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
|
||||
job: Mapped[Job] = relationship(back_populates="events")
|
||||
|
||||
|
||||
class PipelineRun(Base):
|
||||
__tablename__ = "pipeline_runs"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
stage: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
||||
version: Mapped[str] = mapped_column(String(128), nullable=False, index=True)
|
||||
dependency_hash: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="running", index=True)
|
||||
source_id: Mapped[Optional[int]] = mapped_column(ForeignKey("sources.id"), nullable=True, index=True)
|
||||
dataset_id: Mapped[Optional[int]] = mapped_column(ForeignKey("datasets.id"), nullable=True, index=True)
|
||||
job_id: Mapped[Optional[int]] = mapped_column(ForeignKey("jobs.id"), nullable=True, index=True)
|
||||
input_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
output_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
error: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
started_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
finished_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
source: Mapped[Optional[Source]] = relationship()
|
||||
dataset: Mapped[Optional[Dataset]] = relationship()
|
||||
job: Mapped[Optional[Job]] = relationship()
|
||||
|
||||
|
||||
class GtfsAgency(Base):
|
||||
__tablename__ = "gtfs_agencies"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "agency_id", name="uq_gtfs_agency_dataset_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
agency_id: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
name: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
url: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
timezone: Mapped[Optional[str]] = mapped_column(String(128), nullable=True)
|
||||
|
||||
|
||||
class GtfsStop(Base):
|
||||
__tablename__ = "gtfs_stops"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "stop_id", name="uq_gtfs_stop_dataset_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
stop_id: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
parent_station: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||
|
||||
|
||||
class GtfsRoute(Base):
|
||||
__tablename__ = "gtfs_routes"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "route_id", name="uq_gtfs_route_dataset_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
route_id: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
agency_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||
short_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
long_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
route_type: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
|
||||
mode: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
route_scope: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
operator_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
geometry_geojson: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
min_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
min_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
route_key: Mapped[Optional[str]] = mapped_column(Text, nullable=True, index=True)
|
||||
operator_key: Mapped[Optional[str]] = mapped_column(Text, nullable=True, index=True)
|
||||
|
||||
|
||||
class GtfsTrip(Base):
|
||||
__tablename__ = "gtfs_trips"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "trip_id", name="uq_gtfs_trip_dataset_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
route_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
trip_id: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
service_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||
shape_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||
|
||||
|
||||
class GtfsCalendar(Base):
|
||||
__tablename__ = "gtfs_calendars"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "service_id", name="uq_gtfs_calendar_dataset_service"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
service_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
monday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
tuesday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
wednesday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
thursday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
friday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
saturday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
sunday: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
start_date: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
|
||||
end_date: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
|
||||
|
||||
|
||||
class GtfsCalendarDate(Base):
|
||||
__tablename__ = "gtfs_calendar_dates"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "service_id", "date", name="uq_gtfs_calendar_date_dataset_service_date"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
service_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
date: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
|
||||
exception_type: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
|
||||
class GtfsShape(Base):
|
||||
__tablename__ = "gtfs_shapes"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "shape_id", name="uq_gtfs_shape_dataset_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
shape_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
geometry_geojson: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
min_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
min_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
|
||||
|
||||
class GtfsStopTime(Base):
|
||||
__tablename__ = "gtfs_stop_times"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
trip_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
stop_id: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||
stop_sequence: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
arrival_time: Mapped[Optional[str]] = mapped_column(String(32), nullable=True)
|
||||
departure_time: Mapped[Optional[str]] = mapped_column(String(32), nullable=True)
|
||||
arrival_seconds: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True)
|
||||
departure_seconds: Mapped[Optional[int]] = mapped_column(Integer, nullable=True, index=True)
|
||||
|
||||
|
||||
class CanonicalStop(Base):
|
||||
__tablename__ = "canonical_stops"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
stop_key: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, index=True)
|
||||
name: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
normalized_name: Mapped[str] = mapped_column(Text, nullable=False, index=True)
|
||||
lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
mode: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
|
||||
class CanonicalStopLink(Base):
|
||||
__tablename__ = "canonical_stop_links"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("object_type", "dataset_id", "object_id", name="uq_canonical_stop_link_object"),
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
canonical_stop_id: Mapped[int] = mapped_column(ForeignKey("canonical_stops.id"), nullable=False, index=True)
|
||||
layer: Mapped[str] = mapped_column(String(64), nullable=False, index=True) # timetable, visual
|
||||
object_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True) # gtfs_stop, osm_feature
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
object_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
|
||||
external_id: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
role: Mapped[Optional[str]] = mapped_column(String(64), nullable=True)
|
||||
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
|
||||
distance_m: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
|
||||
canonical_stop: Mapped[CanonicalStop] = relationship()
|
||||
|
||||
|
||||
class RoutePattern(Base):
|
||||
__tablename__ = "route_patterns"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
pattern_key: Mapped[str] = mapped_column(String(255), nullable=False, unique=True, index=True)
|
||||
route_ref: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
route_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
mode: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
route_scope: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
operator_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
source_kind: Mapped[str] = mapped_column(String(64), nullable=False, index=True) # osm, gtfs_proposed
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="active", index=True)
|
||||
osm_feature_id: Mapped[Optional[int]] = mapped_column(ForeignKey("osm_features.id"), nullable=True, index=True)
|
||||
gtfs_route_id: Mapped[Optional[int]] = mapped_column(ForeignKey("gtfs_routes.id"), nullable=True, index=True)
|
||||
gtfs_shape_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True, index=True)
|
||||
geometry_geojson: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
min_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
min_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
|
||||
metadata_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
osm_feature: Mapped[Optional["OsmFeature"]] = relationship()
|
||||
gtfs_route: Mapped[Optional[GtfsRoute]] = relationship()
|
||||
|
||||
|
||||
class RoutePatternStop(Base):
|
||||
__tablename__ = "route_pattern_stops"
|
||||
__table_args__ = (UniqueConstraint("route_pattern_id", "sequence", name="uq_route_pattern_stop_sequence"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
route_pattern_id: Mapped[int] = mapped_column(ForeignKey("route_patterns.id"), nullable=False, index=True)
|
||||
canonical_stop_id: Mapped[int] = mapped_column(ForeignKey("canonical_stops.id"), nullable=False, index=True)
|
||||
sequence: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
distance_along: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
source_kind: Mapped[str] = mapped_column(String(64), nullable=False, default="timetable")
|
||||
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
|
||||
|
||||
route_pattern: Mapped[RoutePattern] = relationship()
|
||||
canonical_stop: Mapped[CanonicalStop] = relationship()
|
||||
|
||||
|
||||
class GtfsRoutePatternLink(Base):
|
||||
__tablename__ = "gtfs_route_pattern_links"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "route_id", "shape_id", name="uq_gtfs_route_pattern_shape"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
gtfs_route_id: Mapped[int] = mapped_column(ForeignKey("gtfs_routes.id"), nullable=False, index=True)
|
||||
route_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
shape_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
route_pattern_id: Mapped[int] = mapped_column(ForeignKey("route_patterns.id"), nullable=False, index=True)
|
||||
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=0)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="linked", index=True)
|
||||
source_kind: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
reasons_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
|
||||
gtfs_route: Mapped[GtfsRoute] = relationship()
|
||||
route_pattern: Mapped[RoutePattern] = relationship()
|
||||
|
||||
|
||||
class GtfsTripRoutePatternLink(Base):
|
||||
__tablename__ = "gtfs_trip_route_pattern_links"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "trip_id", name="uq_gtfs_trip_route_pattern"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
trip_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
route_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
shape_id: Mapped[str] = mapped_column(String(255), nullable=False, index=True)
|
||||
route_pattern_id: Mapped[int] = mapped_column(ForeignKey("route_patterns.id"), nullable=False, index=True)
|
||||
source_kind: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=0)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="linked", index=True)
|
||||
|
||||
route_pattern: Mapped[RoutePattern] = relationship()
|
||||
|
||||
|
||||
class OsmFeature(Base):
|
||||
__tablename__ = "osm_features"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "osm_type", "osm_id", name="uq_osm_feature_dataset_type_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
osm_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
osm_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
kind: Mapped[str] = mapped_column(String(64), nullable=False, index=True) # route, stop, terminal, station, infra
|
||||
mode: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
route_scope: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
ref: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
operator: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
network: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
geometry_geojson: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
min_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
min_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
tags_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
route_key: Mapped[Optional[str]] = mapped_column(Text, nullable=True, index=True)
|
||||
operator_key: Mapped[Optional[str]] = mapped_column(Text, nullable=True, index=True)
|
||||
|
||||
|
||||
class OsmAddress(Base):
|
||||
__tablename__ = "osm_addresses"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "osm_type", "osm_id", name="uq_osm_address_dataset_type_id"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
osm_type: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
osm_id: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
housenumber: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
street: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
place: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
postcode: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
city: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
country: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
unit: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
display_name: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
search_text: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
min_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
min_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lon: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
max_lat: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
geometry_geojson: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
tags_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
|
||||
class RoutingNode(Base):
|
||||
__tablename__ = "routing_nodes"
|
||||
__table_args__ = (UniqueConstraint("dataset_id", "osm_node_id", name="uq_routing_node_dataset_osm"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
osm_node_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
|
||||
lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
|
||||
class RoutingEdge(Base):
|
||||
__tablename__ = "routing_edges"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
dataset_id: Mapped[int] = mapped_column(ForeignKey("datasets.id"), nullable=False, index=True)
|
||||
osm_way_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
|
||||
source_osm_node_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
|
||||
target_osm_node_id: Mapped[int] = mapped_column(BigInteger, nullable=False, index=True)
|
||||
source_lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
source_lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
target_lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
target_lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
highway: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
length_m: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
walk_cost_s: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
reverse_walk_cost_s: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
drive_cost_s: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
reverse_drive_cost_s: Mapped[Optional[float]] = mapped_column(Float, nullable=True)
|
||||
geometry_geojson: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
min_lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
min_lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
max_lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
max_lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
tags_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
|
||||
class RouteMatch(Base):
|
||||
__tablename__ = "route_matches"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
gtfs_route_id: Mapped[int] = mapped_column(ForeignKey("gtfs_routes.id"), nullable=False, index=True)
|
||||
osm_feature_id: Mapped[Optional[int]] = mapped_column(ForeignKey("osm_features.id"), nullable=True, index=True)
|
||||
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=0)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False) # matched, probable, weak, missing, accepted, rejected
|
||||
rule_source: Mapped[str] = mapped_column(String(64), default="auto", nullable=False) # auto, manual
|
||||
reasons_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
gtfs_route: Mapped[GtfsRoute] = relationship()
|
||||
osm_feature: Mapped[Optional[OsmFeature]] = relationship()
|
||||
|
||||
|
||||
class MatchRule(Base):
|
||||
__tablename__ = "match_rules"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
rule_type: Mapped[str] = mapped_column(String(64), nullable=False) # accept_match, reject_match, alias, force_operator
|
||||
selector_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
action_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
note: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
|
||||
class JourneySearchCache(Base):
|
||||
__tablename__ = "journey_search_cache"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
cache_key: Mapped[str] = mapped_column(String(128), nullable=False, unique=True, index=True)
|
||||
cache_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
||||
payload_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True)
|
||||
|
||||
|
||||
class TravelRequest(Base):
|
||||
__tablename__ = "travel_requests"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
origin_stop_id: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
destination_stop_id: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
via_stop_id: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
departure_time: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
service_date: Mapped[Optional[str]] = mapped_column(String(10), nullable=True, index=True)
|
||||
max_transfers: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
|
||||
transfer_seconds: Mapped[int] = mapped_column(Integer, nullable=False, default=120)
|
||||
source_filter: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
preferences_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
|
||||
itineraries: Mapped[list["Itinerary"]] = relationship(back_populates="request", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class Itinerary(Base):
|
||||
__tablename__ = "itineraries"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
request_id: Mapped[int] = mapped_column(ForeignKey("travel_requests.id"), nullable=False, index=True)
|
||||
title: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
family: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
|
||||
status: Mapped[str] = mapped_column(String(64), nullable=False, default="candidate", index=True)
|
||||
saved: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
|
||||
summary_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
score_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
payload_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False, index=True)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=now_utc, nullable=False)
|
||||
|
||||
request: Mapped[TravelRequest] = relationship(back_populates="itineraries")
|
||||
legs: Mapped[list["ItineraryLeg"]] = relationship(back_populates="itinerary", cascade="all, delete-orphan")
|
||||
|
||||
|
||||
class ItineraryLeg(Base):
|
||||
__tablename__ = "itinerary_legs"
|
||||
__table_args__ = (UniqueConstraint("itinerary_id", "sequence", name="uq_itinerary_leg_sequence"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
||||
itinerary_id: Mapped[int] = mapped_column(ForeignKey("itineraries.id"), nullable=False, index=True)
|
||||
sequence: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
mode: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, index=True)
|
||||
route_ref: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
route_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
from_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
to_name: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
departure_time: Mapped[Optional[str]] = mapped_column(String(32), nullable=True)
|
||||
arrival_time: Mapped[Optional[str]] = mapped_column(String(32), nullable=True)
|
||||
locked: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False, index=True)
|
||||
payload_json: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
|
||||
|
||||
itinerary: Mapped[Itinerary] = relationship(back_populates="legs")
|
||||
Reference in New Issue
Block a user