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.raob import RAOBReader
from xmet.igra import IGRAStation
parser = argparse.ArgumentParser(
description = 'Ingest RAOB soundings'
@ -27,6 +28,11 @@ for path in getattr(args, 'raob-sounding-file'):
print(f"Ingesting sounding 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:
continue

View file

@ -212,7 +212,7 @@ class Database():
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)
if selectors is None:
@ -225,9 +225,9 @@ class Database():
table.__table__
)
if len(values) > 0:
if len(clauses) > 0:
sql += " where "
sql += " and ".join([f"{table.__table__}.{k} = ?" for k in values])
sql += " and ".join(clauses)
if len(order_by) > 0:
sql += " order by"
@ -247,19 +247,21 @@ class Database():
elif order is DatabaseOrder.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()):
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:
sql = f"select {fn}({column}) as ret from {table.__table__}"
if len(values) > 0:
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

View file

@ -6,7 +6,7 @@ import shapely
from typing import Self
from xmet.db import DatabaseTable
from xmet.db import Database, DatabaseTable
from xmet.coord import COORD_SYSTEM
from xmet.sounding import Sounding, SoundingSample
@ -265,3 +265,18 @@ class IGRAStation(DatabaseTable):
break
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.samples = list(db.query(SoundingSample, {
sounding.samples = list(db.query(SoundingSample,
clauses = [
'sounding_id = :sounding_id'
],
values = {
'sounding_id': sounding.id
}, [['pressure', DatabaseOrder.DESC]]).fetchall())
},
order_by = [[
'pressure', DatabaseOrder.DESC
]]).fetchall())
return sounding
@ -149,8 +156,15 @@ class Sounding(DatabaseTable):
})
sounding = st.fetchone()
sounding.samples = list(db.query(SoundingSample, {
sounding.samples = list(db.query(SoundingSample,
clauses = [
'sounding_id = :sounding_id'
],
values = {
'sounding_id': sounding.id
}, [['pressure', DatabaseOrder.DESC]]).fetchall())
},
order_by = [[
'pressure', DatabaseOrder.DESC
]]).fetchall())
return sounding