TDOE#230: Fix Student Program Dedupe, and add Program Status staging models.#249
Merged
Conversation
…ssociations and student disabilities
…rg responsable for the student's enrollment in the program)
…nce we want the k_lea, k_school, and school_year from the entity/year the student is enrolled in the program in, not when the program was defined.
14 tasks
This was referenced Jun 9, 2026
rlittle08
approved these changes
Jun 9, 2026
6d21849 to
730fe2b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
edu_edfi_sourcethat addsk_student_programand the newprogram_participation_statusesstaging models. Do not merge until that PR is approved and a versioned release is available.Description & motivation
This PR is a subset of TN'S edu_wh PR #230 , pulled forward separately because this piece is ready to ship while the rest of that work is still being scoped. It is the
edu_whcompanion to theedu_edfi_sourcePR that introducesk_student_program.It propagates the new
k_student_programsurrogate key into all eight program association fact tables, adds a newfct_student_program_participation_statuscross-program fact table, and expandsfct_student_program_serviceto include services from the generic program association endpoint.ed_org_idis intentionally not exposed as a standalone column in any of the fact tables since it is fully encoded withink_student_program.Main highlights:
k_student_programadded to all 8 program association fact tables, surfaced as a NOT NULL column and declared in YAML column lists andconstraintsblocks.fct_student_program_participation_statusis a new union-style fact table (same pattern asfct_student_program_service) that stacks participation status rows from all enabled program types into a single table.fct_student_program_servicenow also unions instg_ef3__stu_program__program_services, covering services from the generic program association endpoint that were previously missing.PR Merge Priority:
Changes to existing files:
Parent program association fact table SQLs (cherry-picked from PR #230):
stage.k_student_programto eachformattedCTE SELECT list, and addedalter column k_student_program set not nullto each post_hook. No other logic was changed:fct_student_program_association.sqlfct_student_special_education_program_association.sqlfct_student_cte_program_associations.sqlfct_student_homeless_program_association.sqlfct_student_language_instruction_program_association.sqlfct_student_migrant_education_program_associations.sqlfct_student_school_food_service_program_associations.sqlfct_student_title_i_part_a_program_association.sql:Parent program association fact table YMLs (cherry-picked from PR #230):
k_student_programadded to the column list in each YAML.fct_student_program_service.sql(cherry-picked from PR #230):stg_ef3__stu_program__program_servicesas an unconditional source in the union, so services from the generic program association endpoint are now included.stacked.k_student_programto thesubsetCTE SELECT list.stacked.cip_code(gated bysrc:program:cte:enabled) to thesubsetCTE SELECT list.(k_student, k_program, program_enroll_begin_date, program_service)-->(k_student_program, program_service).Bug fixes caught in review:
ed_org_idfrom the final SELECT of all fact models, as we don't usually bring forward raw ID fields, those tend to only exist within dim tables. Thek_student_programkey contains the ID field as part of its source, so we can retain the proper grain of the table through that key (and k_lea/k_school).fct_student_program_participation_status.sql:stg_ef3__stu_school_food_service__program_services(the services table) instead ofstg_ef3__stu_school_food_service__program_participation_statuses.alter column ed_org_id set not nullpost_hook entry.fct_student_program_service.sql:alter column ed_org_id set not nullpost_hook entry for the same reason.fct_student_program_service.yml:constraintsprimary key from[k_student, k_program, program_enroll_begin_date, program_service]-->[k_student_program, program_service]to match the post_hook.unique_combination_of_columnstest to match.stg_ef3__stu_program__program_servicesto the description's source model list.stg_ef3__stu_title_i__-->stg_ef3__stu_title_i_part_a__).fct_student_special_education_program_association.yml:ed_org_idfrom theunique_combination_of_columnstest.fct_student_program_service.yml:ed_org_idfrom column lists across the board. It was added in the cherry-picked work but is not selected in any of the SQL outputs since it is encoded ink_student_program.(k_student, k_program, program_enroll_begin_date)-->(k_student_program)k_student_program; the surrogate is the correct grain identifier for these tables.fct_student_program_association.yml:`k_student, k_program`-->`k_student, k_program, program_enroll_begin_date`to match the actual constraint and test.New files created:
fct_student_program_participation_status.sql(cherry-picked from PR Feature/tdoe cds enhanced and everwhere 0.6.2 #230): Union fact table that stacksprogram_participation_statusesrecords from all enabled program types, plus the generic program association endpoint unconditionally. Follows the same Jinja union pattern asfct_student_program_service: a list of staging relations is built at compile time, unioned withdbt_utils.union_relations, and asubsetCTE selects the shared columns. rain is one record per student, year, program, ed org, program enrollment begin date, participation status, and status begin date (k_student_program + participation_status + status_begin_date). Joins todim_programto filter on valid programs; FK todim_studentis declared via post_hook for Snowflake metadata.fct_student_program_participation_status.yml: Documentation for the new model. Uses the sameany_varenabled logic asfct_student_program_service. Includesconstraints,unique_combination_of_columnstest onk_student_program + participation_status + status_begin_date, and full column list.Tests and QC done:
dbt compileclean against localedu_edfi_sourcedevelopment branchdbt run --select tag:special_ed tag:cte tag:homeless tag:language_instruction tag:migrant_education tag:food_service tag:title_ipassesfct_student_program_participation_statusuniqueness test passes with real datak_student_programaddition