Look up IGRA stations when possible

Other changes:

* Refactor Database.query() to accept a list of clauses, rather than a
  dict of key-value pairs to build '{k} = :{k}' clauses from
This commit is contained in:
XANTRONIX 2025-03-02 20:02:09 -05:00
parent c9f667301e
commit 6d7b8023c2
4 changed files with 51 additions and 14 deletions

View file

@ -4,6 +4,7 @@ import argparse
from xmet.db import Database from xmet.db import Database
from xmet.raob import RAOBReader from xmet.raob import RAOBReader
from xmet.igra import IGRAStation
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description = 'Ingest RAOB soundings' description = 'Ingest RAOB soundings'
@ -27,6 +28,11 @@ for path in getattr(args, 'raob-sounding-file'):
print(f"Ingesting sounding file {path}") print(f"Ingesting sounding file {path}")
for sounding in RAOBReader.each_sounding_from_file(path): for sounding in RAOBReader.each_sounding_from_file(path):
station = IGRAStation.find_station(db, sounding.station)
if station is not None:
sounding.station = station.code
if args.dry_run: if args.dry_run:
continue continue

View file

@ -212,7 +212,7 @@ class Database():
return cr return cr
def query(self, table, values=dict(), order_by=list()): def query(self, table, clauses=list(), values=None, order_by=list()):
selectors = getattr(table, '__columns_read__', None) selectors = getattr(table, '__columns_read__', None)
if selectors is None: if selectors is None:
@ -225,9 +225,9 @@ class Database():
table.__table__ table.__table__
) )
if len(values) > 0: if len(clauses) > 0:
sql += " where " sql += " where "
sql += " and ".join([f"{table.__table__}.{k} = ?" for k in values]) sql += " and ".join(clauses)
if len(order_by) > 0: if len(order_by) > 0:
sql += " order by" sql += " order by"
@ -247,19 +247,21 @@ class Database():
elif order is DatabaseOrder.DESC: elif order is DatabaseOrder.DESC:
sql += f" {column} desc" sql += f" {column} desc"
return self.query_sql(table, sql, list(values.values())) return self.query_sql(table, sql, values)
def get(self, table, values: dict=dict()): def get(self, table, values: dict=dict()):
return self.query(table, values).fetchone() clauses = [f"{k} = :{k}" for k in values]
return self.query(table, clauses, values=values).fetchone()
def _call(self, table, fn: str, column: str, values: dict=dict()) -> int: def _call(self, table, fn: str, column: str, values: dict=dict()) -> int:
sql = f"select {fn}({column}) as ret from {table.__table__}" sql = f"select {fn}({column}) as ret from {table.__table__}"
if len(values) > 0: if len(values) > 0:
sql += " where " sql += " where "
sql += " and ".join([f"{k} = ?" for k in values]) sql += " and ".join([f"{k} = :{k}" for k in values])
row = self.db.execute(sql, list(values.values())).fetchone() row = self.db.execute(sql, values).fetchone()
return row[0] if row is not None else None return row[0] if row is not None else None

View file

@ -6,7 +6,7 @@ import shapely
from typing import Self from typing import Self
from xmet.db import DatabaseTable from xmet.db import Database, DatabaseTable
from xmet.coord import COORD_SYSTEM from xmet.coord import COORD_SYSTEM
from xmet.sounding import Sounding, SoundingSample from xmet.sounding import Sounding, SoundingSample
@ -265,3 +265,18 @@ class IGRAStation(DatabaseTable):
break break
yield IGRAStation.parse_station(line) yield IGRAStation.parse_station(line)
@staticmethod
def find_station(db: Database, station: str) -> Self:
sql = """
select * from xmet_igra_station where code like concat('%', :code)
"""
return db.query(IGRAStation,
clauses = [
"code like concat('%', :code)"
],
values = {
'code': station
}
).fetchone()

View file

@ -113,9 +113,16 @@ class Sounding(DatabaseTable):
}) })
sounding = st.fetchone() sounding = st.fetchone()
sounding.samples = list(db.query(SoundingSample, { sounding.samples = list(db.query(SoundingSample,
'sounding_id': sounding.id clauses = [
}, [['pressure', DatabaseOrder.DESC]]).fetchall()) 'sounding_id = :sounding_id'
],
values = {
'sounding_id': sounding.id
},
order_by = [[
'pressure', DatabaseOrder.DESC
]]).fetchall())
return sounding return sounding
@ -149,8 +156,15 @@ class Sounding(DatabaseTable):
}) })
sounding = st.fetchone() sounding = st.fetchone()
sounding.samples = list(db.query(SoundingSample, { sounding.samples = list(db.query(SoundingSample,
'sounding_id': sounding.id clauses = [
}, [['pressure', DatabaseOrder.DESC]]).fetchall()) 'sounding_id = :sounding_id'
],
values = {
'sounding_id': sounding.id
},
order_by = [[
'pressure', DatabaseOrder.DESC
]]).fetchall())
return sounding return sounding