diff --git a/CHANGELOG.md b/CHANGELOG.md index e90b9408..e14531de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Unreleased ## New features +- Add `course_level_characteristics_array` column to `dim_course`. This column was previously added to `dim_course_section`. - Added `fct_student_disability`, a new fact table unifying student disabilities from ed org associations and special education program associations into a single model. Includes `is_program` to distinguish the two grains, `k_student_program` for joining to program association fact tables, and extensible boolean designation columns via `xwalk_disability_designations`. - Breaking change: New xwalk is required, `xwalk_disability_designations`, to pivot disability designation descriptors into boolean indicator columns in `fct_student_disability`. Expected columns: `disability_designation_descriptor` (the Ed-Fi descriptor value to match) and `indicator_name` (the name of the resulting boolean column). If the seed is empty, the designation columns are omitted and the model builds without them. ## Under the hood diff --git a/models/build/edfi_3/courses/bld_ef3__course__wide_course_characteristics.sql b/models/build/edfi_3/courses/bld_ef3__course__wide_course_characteristics.sql new file mode 100644 index 00000000..51e3c897 --- /dev/null +++ b/models/build/edfi_3/courses/bld_ef3__course__wide_course_characteristics.sql @@ -0,0 +1,39 @@ +with courses as ( + select * from {{ ref('stg_ef3__courses') }} +), +xwalk_course_level_characteristics as ( + select * from {{ ref('xwalk_course_level_characteristics') }} +), +flattened as ( + select + tenant_code, + api_year, + k_course, + {{ edu_edfi_source.extract_descriptor('course_chars.value:courseLevelCharacteristicDescriptor::string') }} as course_characteristic + from courses + {{ edu_edfi_source.json_flatten('v_level_characteristics', 'course_chars', outer=true) }} +), +pivoted as ( + select + tenant_code, + api_year, + k_course, + {{ edu_edfi_source.json_array_agg( + 'course_characteristic', + order_by='course_characteristic', + is_terminal=True + ) }} as course_characteristics_array + {%- if not is_empty_model('xwalk_course_level_characteristics') -%}, + {{ ea_pivot( + column='indicator_name', + values=dbt_utils.get_column_values(ref('xwalk_course_level_characteristics'), 'indicator_name'), + cast='boolean', + ) }} + {%- endif %} + from flattened + left outer join xwalk_course_level_characteristics + on flattened.course_characteristic = xwalk_course_level_characteristics.characteristic_descriptor + group by all +) +select * +from pivoted \ No newline at end of file diff --git a/models/build/edfi_3/courses/bld_ef3__course_char__combined_long.sql b/models/build/edfi_3/courses/bld_ef3__course_char__combined_long.sql index d18af013..801153c5 100644 --- a/models/build/edfi_3/courses/bld_ef3__course_char__combined_long.sql +++ b/models/build/edfi_3/courses/bld_ef3__course_char__combined_long.sql @@ -63,6 +63,7 @@ unioned as ( select tenant_code, api_year, + k_course, k_course_section, characteristic as course_level_characteristic from unioned diff --git a/models/build/edfi_3/courses/bld_ef3__course_char__combined_wide.sql b/models/build/edfi_3/courses/bld_ef3__course_char__combined_wide.sql index 7a8ae21e..90ddc4f5 100644 --- a/models/build/edfi_3/courses/bld_ef3__course_char__combined_wide.sql +++ b/models/build/edfi_3/courses/bld_ef3__course_char__combined_wide.sql @@ -9,6 +9,7 @@ pivoted as ( select tenant_code, api_year, + k_course, k_course_section, {{ edu_edfi_source.json_array_agg( 'course_level_characteristic', diff --git a/models/core_warehouse/dim_course.sql b/models/core_warehouse/dim_course.sql index bed782a1..4bcf2fd2 100644 --- a/models/core_warehouse/dim_course.sql +++ b/models/core_warehouse/dim_course.sql @@ -19,6 +19,9 @@ bld_ef3__wide_ids_course as ( bld_ef3__course_subject as ( select * from {{ ref('bld_ef3__course_subject') }} ), +course_chars as ( + select * from {{ ref('bld_ef3__course__wide_course_characteristics') }} +), formatted as ( select stg_course.k_course, @@ -50,6 +53,15 @@ formatted as ( stg_course.number_of_parts, stg_course.time_required_for_completion, + -- course characteristics + {{ accordion_columns( + source_table='bld_ef3__course__wide_course_characteristics', + exclude_columns=['tenant_code', 'api_year', 'k_course', 'course_characteristics_array'], + source_alias='course_chars', + coalesce_value = 'FALSE' + ) }} + course_chars.course_characteristics_array, + -- custom indicators {% if custom_data_sources is not none and custom_data_sources | length -%} {%- for source in custom_data_sources -%} @@ -67,6 +79,8 @@ formatted as ( on stg_course.k_course = bld_ef3__wide_ids_course.k_course left join bld_ef3__course_subject on stg_course.k_course = bld_ef3__course_subject.k_course + left join course_chars + on stg_course.k_course = course_chars.k_course -- custom data sources {% if custom_data_sources is not none and custom_data_sources | length -%} diff --git a/models/core_warehouse/dim_course.yml b/models/core_warehouse/dim_course.yml index 3b3efd0c..5ca8cd93 100644 --- a/models/core_warehouse/dim_course.yml +++ b/models/core_warehouse/dim_course.yml @@ -76,6 +76,8 @@ models: - name: time_required_for_completion description: "The actual or estimated number of clock minutes required for class completion. This number is especially important for career and technical education classes and may represent (in minutes) the clock hour requirement of the class." + - name: course_characteristics_array + description: A list of all the course level characteristics associated with the course. - name: subject_array description: A list of all the academic subjects associated with the course.