Use indexed raw observation history lookup

This commit is contained in:
2569718930@qq.com
2026-06-15 19:47:17 +08:00
parent 7a9573c214
commit 4ff334aec4
2 changed files with 22 additions and 13 deletions
+12 -7
View File
@@ -1307,20 +1307,25 @@ class DBManager:
return [] return []
safe_limit = max(1, min(int(limit or 1000), 5000)) safe_limit = max(1, min(int(limit or 1000), 5000))
safe_minutes = max(1, min(int(minutes or 60), 7 * 24 * 60)) safe_minutes = max(1, min(int(minutes or 60), 7 * 24 * 60))
cutoff_ts = datetime.now().timestamp() - safe_minutes * 60 cutoff_dt = datetime.now(timezone.utc) - timedelta(minutes=safe_minutes)
cutoff_observed_at = cutoff_dt.replace(microsecond=0).isoformat()
with self._get_connection() as conn: with self._get_connection() as conn:
conn.row_factory = sqlite3.Row conn.row_factory = sqlite3.Row
rows = conn.execute( rows = conn.execute(
""" """
SELECT * SELECT *
FROM raw_observation_store FROM (
WHERE source = ? SELECT *
AND city = ? FROM raw_observation_store
AND created_at_ts >= ? WHERE source = ?
AND city = ?
AND observed_at >= ?
ORDER BY observed_at DESC, fetched_at DESC, created_at_ts DESC
LIMIT ?
)
ORDER BY observed_at ASC, fetched_at ASC, created_at_ts ASC ORDER BY observed_at ASC, fetched_at ASC, created_at_ts ASC
LIMIT ?
""", """,
(normalized_source, normalized_city, cutoff_ts, safe_limit), (normalized_source, normalized_city, cutoff_observed_at, safe_limit),
).fetchall() ).fetchall()
out: List[Dict[str, Any]] = [] out: List[Dict[str, Any]] = []
for row in rows: for row in rows:
+10 -6
View File
@@ -182,15 +182,19 @@ def test_raw_observation_store_records_latest_observation(tmp_path):
def test_raw_observation_store_lists_source_city_history(tmp_path): def test_raw_observation_store_lists_source_city_history(tmp_path):
from datetime import datetime, timedelta, timezone
from src.database.db_manager import DBManager from src.database.db_manager import DBManager
db = DBManager(str(tmp_path / "polyweather.db")) db = DBManager(str(tmp_path / "polyweather.db"))
first_observed_at = (datetime.now(timezone.utc) - timedelta(minutes=2)).replace(microsecond=0).isoformat()
second_observed_at = (datetime.now(timezone.utc) - timedelta(minutes=1)).replace(microsecond=0).isoformat()
db.append_raw_observation( db.append_raw_observation(
source="amsc_awos", source="amsc_awos",
city="Chengdu", city="Chengdu",
value=25.6, value=25.6,
observed_at="2026-06-15T11:04:00+00:00", observed_at=first_observed_at,
fetched_at="2026-06-15T11:04:30+00:00", fetched_at=first_observed_at,
station_code="ZUUU", station_code="ZUUU",
payload={"temp_c": 25.6}, payload={"temp_c": 25.6},
) )
@@ -198,8 +202,8 @@ def test_raw_observation_store_lists_source_city_history(tmp_path):
source="amsc_awos", source="amsc_awos",
city="chengdu", city="chengdu",
value=25.4, value=25.4,
observed_at="2026-06-15T11:08:00+00:00", observed_at=second_observed_at,
fetched_at="2026-06-15T11:08:30+00:00", fetched_at=second_observed_at,
station_code="ZUUU", station_code="ZUUU",
payload={"temp_c": 25.4}, payload={"temp_c": 25.4},
) )
@@ -207,8 +211,8 @@ def test_raw_observation_store_lists_source_city_history(tmp_path):
rows = db.list_raw_observation_history("amsc_awos", "chengdu", minutes=60, limit=10) rows = db.list_raw_observation_history("amsc_awos", "chengdu", minutes=60, limit=10)
assert [row["observed_at"] for row in rows] == [ assert [row["observed_at"] for row in rows] == [
"2026-06-15T11:04:00+00:00", first_observed_at,
"2026-06-15T11:08:00+00:00", second_observed_at,
] ]
assert rows[-1]["payload"]["temp_c"] == 25.4 assert rows[-1]["payload"]["temp_c"] == 25.4