diff --git a/backend/app.py b/backend/app.py index cf23dff..e50dd50 100644 --- a/backend/app.py +++ b/backend/app.py @@ -330,6 +330,11 @@ async def get_schools( if page_size is None: page_size = settings.default_page_size + # Schools with no performance data (special schools, PRUs, newly opened, etc.) + # have NULL year from the LEFT JOIN — keep them but skip the groupby/trend logic. + df_no_perf = df[df["year"].isna()].drop_duplicates(subset=["urn"]) + df = df[df["year"].notna()] + # Get unique schools (latest year data for each) latest_year = df.groupby("urn")["year"].max().reset_index() df_latest = df.merge(latest_year, on=["urn", "year"]) @@ -351,6 +356,9 @@ async def get_schools( ) df_latest = df_latest.merge(prev_rwm, on="urn", how="left") + # Merge back schools with no performance data + df_latest = pd.concat([df_latest, df_no_perf], ignore_index=True) + # Phase filter — uses PHASE_GROUPS so all-through/middle schools appear # in the correct phase(s) rather than being invisible to both filters. if phase: diff --git a/backend/data_loader.py b/backend/data_loader.py index c791a4b..1cfbbc1 100644 --- a/backend/data_loader.py +++ b/backend/data_loader.py @@ -199,7 +199,7 @@ _MAIN_QUERY = text(""" p.sen_ehcp_pct FROM marts.dim_school s JOIN marts.dim_location l ON s.urn = l.urn - JOIN marts.fact_performance p ON s.urn = p.urn + LEFT JOIN marts.fact_performance p ON s.urn = p.urn ORDER BY s.school_name, p.year """) @@ -244,7 +244,7 @@ def load_school_data() -> pd.DataFrame: if not _df_cache.empty: print(f"Total records loaded: {len(_df_cache)}") print(f"Unique schools: {_df_cache['urn'].nunique()}") - print(f"Years: {sorted(_df_cache['year'].unique())}") + print(f"Years: {sorted(_df_cache['year'].dropna().unique())}") else: print("No data found in marts (EES data may not have been loaded yet)") return _df_cache diff --git a/docker-compose.yml b/docker-compose.yml index c411b4a..f72bb7a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,7 @@ services: POSTGRES_USER: schoolcompare POSTGRES_PASSWORD: schoolcompare POSTGRES_DB: schoolcompare + POSTGRES_INITDB_ARGS: "--locale=C --encoding=UTF8" volumes: - postgres_data:/var/lib/postgresql/data ports: