Skip to content

Commit d144ae0

Browse files
committed
remoed duckdb spatial ext from the dashboard and added pyarrow
1 parent ad795c3 commit d144ae0

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

app.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
def make_conn():
4646
conn = duckdb.connect()
47-
conn.execute("INSTALL spatial; LOAD spatial;")
47+
# No spatial extension — dashboard only reads scalar columns from parquet
4848
conn.execute(f"""
4949
CREATE SECRET IF NOT EXISTS s3_secret (
5050
TYPE s3,
@@ -83,7 +83,9 @@ def read_ts(country, aoi_name):
8383
try:
8484
df = CONN.execute(f"""
8585
SELECT time, ndvi, bsi, ndmi, nbr
86-
FROM read_parquet('{glob}')
86+
FROM read_parquet('{glob}',
87+
union_by_name=true,
88+
hive_partitioning=false)
8789
WHERE aoi_name = '{aoi_name}'
8890
AND time > '2018-01-01'
8991
ORDER BY time
@@ -94,7 +96,28 @@ def read_ts(country, aoi_name):
9496
except Exception as e:
9597
print(f"read_ts error: {e}")
9698
traceback.print_exc()
97-
return pd.DataFrame()
99+
# Fallback: use boto3 + pyarrow to read parquet directly
100+
try:
101+
import boto3, io, pyarrow.parquet as pq
102+
s3 = boto3.client("s3")
103+
prefix = f"{country}/{aoi_name}/ts/"
104+
resp = s3.list_objects_v2(Bucket=BUCKET, Prefix=prefix)
105+
dfs = []
106+
for obj in resp.get("Contents", []):
107+
if obj["Key"].endswith(".parquet"):
108+
buf = io.BytesIO(s3.get_object(Bucket=BUCKET, Key=obj["Key"])["Body"].read())
109+
tbl = pq.read_table(buf, columns=["time","ndvi","bsi","ndmi","nbr","aoi_name"])
110+
dfs.append(tbl.to_pandas())
111+
if not dfs:
112+
return pd.DataFrame()
113+
df = pd.concat(dfs)
114+
df = df[df["aoi_name"] == aoi_name].query("time > '2018-01-01'").sort_values("time")
115+
df["time"] = pd.to_datetime(df["time"])
116+
print(f"read_ts fallback OK: {df.shape}")
117+
return df[["time","ndvi","bsi","ndmi","nbr"]]
118+
except Exception as e2:
119+
print(f"read_ts fallback error: {e2}")
120+
return pd.DataFrame()
98121

99122
def read_forecasts(country, aoi_name):
100123
glob = f"s3://{BUCKET}/{country}/{aoi_name}/ml/forecast_{aoi_name}_*.parquet"

0 commit comments

Comments
 (0)