mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
413c46b5dd
Trzy usterki uniemożliwiające uruchomienie stosu lokalnie: 1. Warstwa danych wykładała się na starcie przy zapisie Parquet dla realnych plików (np. Encyclopaedia of Medical Astrology) — kolumny o mieszanych typach (int+str+NaN). frame_cache.put() zapisuje teraz ramkę jako string (warstwa i tak wyszukuje po tekście). Dodatkowo warmup() jest odporny: pojedynczy uszkodzony plik nie blokuje startu usługi. 2. Brakowało kroku instalacji zależności — dev-logic/dev-presentation padały na 'No module named httpx'. Nowy cel `make install` instaluje zależności WSZYSTKICH warstw do aktywnego venv. README zaktualizowane (instalowało wcześniej tylko warstwę danych). 3. `make up` zakładał `docker compose`, którego użytkownik nie ma. Makefile wykrywa `docker compose` lub `docker-compose`, a przy braku obu podaje czytelną instrukcję trybu lokalnego. Dodano `make test` i `make clean-cache`. Zweryfikowane end-to-end na realnym środowisku (.env, Python 3.14) i danych: warmup przechodzi (3 pliki), cały stos wstaje, formularz → logika → silnik Skyfield zwraca poprawne pozycje. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
41 lines
1.6 KiB
Python
41 lines
1.6 KiB
Python
"""Cache danych: znormalizowany arkusz zapisany jako Parquet.
|
||
|
||
POZIOM 2 cache — największy zysk wydajności. Parsowanie .xlsx jest wolne
|
||
(dziesiątki–setki ms na duży plik). Po pierwszym wczytaniu zapisujemy
|
||
znormalizowaną ramkę jako Parquet (kolumnowy, kompresowany), kluczowaną odciskiem
|
||
pliku. Kolejne odczyty ładują Parquet — zwykle 10–100x szybciej niż .xlsx i bez
|
||
ponownego wykrywania nagłówka.
|
||
|
||
Plik Parquet jest też naturalnym formatem pośrednim przy migracji do SQL.
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
import pandas as pd
|
||
|
||
|
||
class FrameCache:
|
||
def __init__(self, cache_dir: Path) -> None:
|
||
self.dir = cache_dir / "frames"
|
||
self.dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
def _path(self, fp: str, sheet: str) -> Path:
|
||
safe = fp.replace(":", "_") + "__" + str(sheet).replace("/", "_")
|
||
return self.dir / f"{safe}.parquet"
|
||
|
||
def get(self, fp: str, sheet: str) -> pd.DataFrame | None:
|
||
p = self._path(fp, sheet)
|
||
if p.exists():
|
||
return pd.read_parquet(p)
|
||
return None
|
||
|
||
def put(self, fp: str, sheet: str, frame: pd.DataFrame) -> None:
|
||
# Kolumny z heterogenicznych plików Excela bywają mieszane (int + str +
|
||
# NaN w jednej kolumnie) — pyarrow tego nie zapisze. Warstwa danych i tak
|
||
# operuje na tekście (wyszukiwanie po .astype(str)), więc zapisujemy ramkę
|
||
# jako string (brak wartości -> pusty tekst). Gwarantuje to stabilny zapis
|
||
# Parquet niezależnie od zawartości pliku źródłowego.
|
||
safe = frame.astype("string").fillna("")
|
||
safe.to_parquet(self._path(fp, sheet), index=False)
|