Part of PLAT-2436, this is an attempt to discover where the StudentModule model and table are read/written, for the purpose of crafting a solution to update its primary key from a signed int to an unsigned bigint.
Direct access to the StudentModule model:
Selects
- The class dashboard aggregates or selects across many StudentModule rows in single queries in these places:
- https://github.com/edx/edx-platform/blob/master/lms/djangoapps/class_dashboard/dashboard_data.py#L37
- https://github.com/edx/edx-platform/blob/master/lms/djangoapps/class_dashboard/dashboard_data.py#L80
- https://github.com/edx/edx-platform/blob/master/lms/djangoapps/class_dashboard/dashboard_data.py#L109
- https://github.com/edx/edx-platform/blob/master/lms/djangoapps/class_dashboard/dashboard_data.py#L430
- https://github.com/edx/edx-platform/blob/master/lms/djangoapps/class_dashboard/dashboard_data.py#L494
- Direct aggregate SELECT SQL executed here:
- https://github.com/edx/edx-platform/blob/master/openedx/core/lib/xblock_utils/__init__.py#L271
- Comment: "Print out a histogram of grades on a given problem in staff member debug info."
- CourseBlocks
- Gets a single user/course/block row: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/course_blocks/utils.py#L25
- Courseware ScoresClient
- Gets multiple user/course/block rows: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/model_data.py#L952
- Courseware model data
Courseware DjangoXBlockUserStateClient
- Get on multiple user/course/block rows using a chunked_filter: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/user_state_client.py#L81
- Paginated iterator over all StudentModule objects for a given XBlock locator, pulling back rows in chunks: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/user_state_client.py#L414
- Paginated iterator over all StudentModule objects for a given course, pulling back rows in chunks: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/user_state_client.py#L428
- Courseware views
- Gets all rows for a student/usage key/course (to then get their history): https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/views/views.py#L1200
- Grades
- Mgmt command
recalculate_subsection_grades
pulls all rows for a learner/course/subsection modified within a certain time: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/grades/management/commands/recalculate_subsection_grades.py#L64
- Mgmt command
- Instructor
reset_student_attempts
gets a single student/course/module state key: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor/enrollment.py#L292
- instructor_analytics
list_problem_responses
gets all answers to a single problem for a course, optionally in chunks: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor_analytics/basic.py#L436
- instructor_task
_get_modules_to_update
fetches all rows for a course / list of usage keys / optional user, also does aget_or_create
:
- The admin site
Writes
- Instructor enrollment:
- Resets the number of attempts on a problem via
save()
: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor/enrollment.py#L324
- Resets the number of attempts on a problem via
- CourseBlocks
- Courseware
get_or_create
for an individual row, plus a get, plus an update: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/model_data.py#L993
- DjangoXBlockUserStateClient
get_or_create
in a loop, with potential updates usingsave()
: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/user_state_client.py#L246
- Instructor
reset_student_attempts
overwrites 'attempts' usingsave()
: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor/enrollment.py#L337
- instructor_task
-
_get_modules_to_update
does a get_or_create in a loop: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor_task/tasks_helper/module_state.py#L427
-
- xmodule
- lti_2_util
set_user_module_score
publishes an event that claims to update StudentModule state, but I'm not sure what the code path for that is: https://github.com/edx/edx-platform/blob/master/common/lib/xmodule/xmodule/lti_2_util.py#L258
- lti_2_util
- The admin site
Deletes
- Instructor
- reset_student_attempts can optionally delete StudentModule rows recursively: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor/enrollment.py#L299
- The admin site
Caches
- I'm unclear on how many of the caches and K/V stores in courseaware/model_data.py access or store StudentModule data, ex: DjangoKeyValueStore & FieldDataCache: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/model_data.py#L680
- courseware.masquerade
MasqueradingKeyValueStore
may also store state?: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/courseware/masquerade.py#L222
Indirect access to StudentModule
- LTI forces a publish of a user's score on a problem in these two places, which claims to eventually write to StudentModule:
- instructor_task _get_module_instance_for_task indirectly reads via DjangoKeyValueStore: https://github.com/edx/edx-platform/blob/master/lms/djangoapps/instructor_task/tasks_helper/module_state.py#L329
Special cases
- Tests that rely on StudentModuleFactory (many)
- Obviously our fix must support or work around sqllite as well
- BokChoy tests use a cached schema that may need to be taken into consideration:
- Tests that check query counts on these tables:
StudentModuleHistoryExtended
- Has event listeners an StudentModule for
post_save
andpost_delete
- Has event listeners an StudentModule for