Files
2026-09-28 17:10:20 +03:00

82 lines
2.6 KiB
Python

import datetime
from collections.abc import Sequence
from dataclasses import dataclass
from sqlalchemy import Date, DateTime, Float, Integer, String, UniqueConstraint, select
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column
from sqlalchemy.sql import func
class Base(DeclarativeBase):
pass
class WeatherForecast(Base):
__tablename__ = "weather_forecast"
__table_args__ = (
UniqueConstraint("city", "forecast_date", name="unique_city_forecast_date"),
)
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
city: Mapped[str] = mapped_column(String, nullable=False)
forecast_date: Mapped[datetime.date] = mapped_column(Date, nullable=False)
temp_min: Mapped[float] = mapped_column(Float, nullable=False)
temp_max: Mapped[float] = mapped_column(Float, nullable=False)
humidity: Mapped[int] = mapped_column(Integer, nullable=False)
wind_speed: Mapped[float] = mapped_column(Float, nullable=False)
description: Mapped[str | None] = mapped_column(String, nullable=True)
created_at: Mapped[datetime.datetime] = mapped_column(
DateTime, default=func.now(), nullable=False
)
def __repr__(self) -> str:
return (
f"WeatherForecast(id={self.id!r}, city={self.city!r}, "
f"forecast_date={self.forecast_date!r}, temp_min={self.temp_min!r}, "
f"temp_max={self.temp_max!r}, humidity={self.humidity!r}, "
f"wind_speed={self.wind_speed!r}, description={self.description!r})"
)
@dataclass(frozen=True)
class DailyForecast:
city: str
forecast_date: datetime.date
temp_min: float
temp_max: float
humidity: int
wind_speed: float
description: str
def save_forecasts(session: Session, forecasts: Sequence[DailyForecast]) -> int:
if not forecasts:
return 0
known: dict[str, set[datetime.date]] = {}
for city in {f.city for f in forecasts}:
known[city] = set(
session.scalars(
select(WeatherForecast.forecast_date).where(
WeatherForecast.city == city
)
).all()
)
add = [
WeatherForecast(
city=f.city,
forecast_date=f.forecast_date,
temp_min=f.temp_min,
temp_max=f.temp_max,
humidity=f.humidity,
wind_speed=f.wind_speed,
description=f.description,
)
for f in forecasts
if f.forecast_date not in known[f.city]
]
session.add_all(add)
session.commit()
return len(add)