PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m2s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 10s
PR Checks / Build Frontend (no push) (pull_request) Successful in 45s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 38s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 54s
Beechwood College (URN 142458, Sully, CF64 5SE) survived the England-only filter. GIAS types it a Special post 16 institution (32), not a Welsh establishment (30), so filtering on establishment type alone left it behind — the last Welsh school on the site, and the reason Vale of Glamorgan was still in the authority list. The earlier verification claimed the type codes mapped onto the Welsh authorities in both directions. That was checked exhaustively for Cardiff and by count for three others; Vale of Glamorgan was never checked, and it was the one that did not hold. LA code is the reliable discriminator: GIAS gives the 22 Welsh unitary authorities the contiguous block 660-681, which English authorities never use. Filtering on postcode would have been wrong — Redbrook, Tutshill, Wyedean and two other Gloucestershire schools carry NP16/NP25 postcodes because Royal Mail areas straddle the border, and they are English schools with English data. An e2e test now pins those five so the fix cannot be simplified into a postcode filter later. The 660-681 range is documented GIAS structure this project cannot verify from its own data, so the range filters and the authority NAME checks: if the range is ever wrong, a Welsh authority reappears in assert_england_only_schools and the pipeline fails loudly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj
101 lines
4.3 KiB
SQL
101 lines
4.3 KiB
SQL
-- Mart: Canonical school dimension — one row per active URN
|
|
|
|
-- int_ofsted_latest is only ref()'d inside a conditional block below (it may not
|
|
-- exist before the Ofsted pipeline first runs), so declare the dependency
|
|
-- explicitly for dbt's DAG.
|
|
-- depends_on: {{ ref('int_ofsted_latest') }}
|
|
|
|
with schools as (
|
|
select * from {{ ref('stg_gias_establishments') }}
|
|
)
|
|
|
|
{% set ofsted_relation = adapter.get_relation(
|
|
database=target.database,
|
|
schema='intermediate',
|
|
identifier='int_ofsted_latest'
|
|
) %}
|
|
|
|
select
|
|
s.urn,
|
|
s.local_authority_code * 1000 + s.establishment_number as laestab,
|
|
s.school_name,
|
|
-- Phase in GIAS code space (see seeds/gias_code_names.csv):
|
|
-- 2 = Primary, 4 = Secondary, 7 = All-through, 0 = Not applicable.
|
|
case
|
|
-- 1. Trust GIAS phase when it's a real value (0 = the catch-all "Not Applicable")
|
|
when s.phase_code is not null and s.phase_code != 0
|
|
then s.phase_code
|
|
-- 2. Infer from statutory age range (independent schools still publish these)
|
|
when s.statutory_high_age is not null and s.statutory_high_age <= 11 then 2
|
|
when s.statutory_low_age is not null and s.statutory_low_age >= 11 then 4
|
|
when s.statutory_low_age is not null and s.statutory_high_age is not null
|
|
and s.statutory_low_age < 11 and s.statutory_high_age > 11 then 7
|
|
-- 3. Fallback: infer from school name (covers independents with missing ages)
|
|
when s.school_name ilike '%primary%'
|
|
or s.school_name ilike '%infant%'
|
|
or s.school_name ilike '%junior%'
|
|
or s.school_name ilike '%preparatory%'
|
|
or s.school_name ilike '% prep school%'
|
|
or s.school_name ilike '% prep %'
|
|
then 2
|
|
when s.school_name ilike '%secondary%'
|
|
or s.school_name ilike '%high school%'
|
|
or s.school_name ilike '%grammar%'
|
|
or s.school_name ilike '%senior school%'
|
|
or s.school_name ilike '%upper school%'
|
|
then 4
|
|
-- 4. Give up — null renders no phase pill
|
|
else null
|
|
end as phase_code,
|
|
s.school_type_code,
|
|
s.academy_trust_name,
|
|
s.academy_trust_uid,
|
|
s.religious_character_code,
|
|
s.gender,
|
|
s.statutory_low_age || '-' || s.statutory_high_age as age_range,
|
|
-- GIAS OfficialSixthForm in code space: 1 = has, 2 = does not, 0 = N/A.
|
|
-- Null (rare, new establishments) falls back to the statutory age range.
|
|
case
|
|
when s.official_sixth_form_code = 1 then true
|
|
when s.official_sixth_form_code in (0, 2) then false
|
|
else coalesce(s.statutory_high_age >= 18, false)
|
|
end as has_sixth_form,
|
|
s.capacity,
|
|
s.total_pupils,
|
|
concat_ws(' ', s.head_title, s.head_first_name, s.head_last_name) as headteacher_name,
|
|
s.website,
|
|
s.telephone,
|
|
s.open_date,
|
|
s.close_date,
|
|
s.status_code,
|
|
s.nursery_provision,
|
|
s.admissions_policy_code,
|
|
|
|
-- Latest Ofsted (populated after monthly Ofsted pipeline runs)
|
|
{% if ofsted_relation is not none %}
|
|
-- Prefer the graded overall effectiveness; fall back to the grade parsed
|
|
-- from the latest ungraded (Section 8) outcome when no graded grade exists.
|
|
coalesce(o.overall_effectiveness, o.ungraded_grade) as ofsted_grade,
|
|
o.inspection_date as ofsted_date,
|
|
o.framework as ofsted_framework
|
|
{% else %}
|
|
null::text as ofsted_grade,
|
|
null::date as ofsted_date,
|
|
null::text as ofsted_framework
|
|
{% endif %}
|
|
|
|
from schools s
|
|
{% if ofsted_relation is not none %}
|
|
left join {{ ref('int_ofsted_latest') }} o on s.urn = o.urn
|
|
{% endif %}
|
|
-- 1 = Open; 3 = Open, but proposed to close (still operating; drops out when
|
|
-- GIAS flips to Closed — marts fully rebuild each run).
|
|
where s.status_code in (1, 3)
|
|
-- England only. dim_location must apply this filter identically (the API
|
|
-- inner-joins the two). See vars in dbt_project.yml for what the codes are.
|
|
-- coalesce, not a bare NOT IN: a null type code would make the predicate
|
|
-- null and drop the row silently. Unknown type is not grounds for exclusion.
|
|
and coalesce(s.school_type_code, -1) not in ({{ var('non_england_school_type_codes') | join(', ') }})
|
|
-- Welsh schools GIAS does not type as Welsh establishments (see vars).
|
|
and coalesce(s.local_authority_code, -1) not between {{ var('welsh_la_code_min') }} and {{ var('welsh_la_code_max') }}
|