"""SQLAlchemy models for fact tables.""" from sqlalchemy import ForeignKey, Integer, Numeric, String from sqlalchemy.orm import Mapped, mapped_column, relationship from .base import Base class FactPurchases(Base): """Fact table for TRREB purchase/sales data. Grain: One row per district per month. """ __tablename__ = "fact_purchases" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) date_key: Mapped[int] = mapped_column( Integer, ForeignKey("dim_time.date_key"), nullable=False ) district_key: Mapped[int] = mapped_column( Integer, ForeignKey("dim_trreb_district.district_key"), nullable=False ) sales_count: Mapped[int] = mapped_column(Integer, nullable=False) dollar_volume: Mapped[float] = mapped_column(Numeric(15, 2), nullable=False) avg_price: Mapped[float] = mapped_column(Numeric(12, 2), nullable=False) median_price: Mapped[float] = mapped_column(Numeric(12, 2), nullable=False) new_listings: Mapped[int] = mapped_column(Integer, nullable=False) active_listings: Mapped[int] = mapped_column(Integer, nullable=False) avg_dom: Mapped[int] = mapped_column(Integer, nullable=False) # Days on market avg_sp_lp: Mapped[float] = mapped_column( Numeric(5, 2), nullable=False ) # Sale/List ratio # Relationships time = relationship("DimTime", backref="purchases") district = relationship("DimTRREBDistrict", backref="purchases") class FactRentals(Base): """Fact table for CMHC rental market data. Grain: One row per zone per bedroom type per survey year. """ __tablename__ = "fact_rentals" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) date_key: Mapped[int] = mapped_column( Integer, ForeignKey("dim_time.date_key"), nullable=False ) zone_key: Mapped[int] = mapped_column( Integer, ForeignKey("dim_cmhc_zone.zone_key"), nullable=False ) bedroom_type: Mapped[str] = mapped_column(String(20), nullable=False) universe: Mapped[int | None] = mapped_column(Integer, nullable=True) avg_rent: Mapped[float | None] = mapped_column(Numeric(10, 2), nullable=True) median_rent: Mapped[float | None] = mapped_column(Numeric(10, 2), nullable=True) vacancy_rate: Mapped[float | None] = mapped_column(Numeric(5, 2), nullable=True) availability_rate: Mapped[float | None] = mapped_column( Numeric(5, 2), nullable=True ) turnover_rate: Mapped[float | None] = mapped_column(Numeric(5, 2), nullable=True) rent_change_pct: Mapped[float | None] = mapped_column(Numeric(5, 2), nullable=True) reliability_code: Mapped[str | None] = mapped_column(String(2), nullable=True) # Relationships time = relationship("DimTime", backref="rentals") zone = relationship("DimCMHCZone", backref="rentals")