POST app.rid.go.th/reservoir/api/dams (open, archive >=2009) collected hourly into rid_dams + rid_reservoir_daily; backfill script fetches only missing days so reruns repair holes and are safe alongside the live collector. /api/stats counts the new table via an engine fallback that works when HII collection is disabled. Mae Ngat (DAM_ID 200103) hit 113% usable capacity with ~19 MCM/day inflow in the Oct 2024 flood — candidate features for the next retrain.
49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Backfill the openmeteo_rain table with the full 2021+ catchment history.
|
|
|
|
Usage:
|
|
uv run scripts/backfill_rain_db.py # DB from Config/.env
|
|
uv run scripts/backfill_rain_db.py --db-url postgresql://...
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
from src.config import Config
|
|
from src.ml.rain import backfill_db
|
|
|
|
|
|
def main(argv=None) -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--db-url", default=None)
|
|
args = parser.parse_args(argv)
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s"
|
|
)
|
|
if args.db_url:
|
|
# postgresql+psycopg2://... -> postgresql (driver suffix is not a dialect)
|
|
connection_string = args.db_url
|
|
db_type = args.db_url.split(":", 1)[0].split("+", 1)[0]
|
|
else:
|
|
cfg = Config.get_database_config()
|
|
if cfg["type"] not in ("sqlite", "postgresql", "mysql"):
|
|
print(f"requires a SQL database, got {cfg['type']}", file=sys.stderr)
|
|
return 1
|
|
connection_string, db_type = cfg["connection_string"], cfg["type"]
|
|
|
|
from sqlalchemy import create_engine
|
|
|
|
engine = create_engine(connection_string, pool_pre_ping=True)
|
|
saved = backfill_db(engine, db_type)
|
|
print(f"backfilled {saved} hourly rows into openmeteo_rain")
|
|
return 0 if saved else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|