Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Below I'm cataloging each and every read/write access to the courseware StudentModule (CSM) Django model. It's essential to know of each access due to our pending work to encapsulate all CSM access behind an interface. The interface backend will support both the present Django ORM and a Cassandra backend to better handle student traffic at scale. Dave Ormsbee has authored this page to capture existing CSM query patterns - the catalog below looks at all code in edx-platform and catalogs access in each file therein.

lms/djangoapps/courseware/model_data.py

Reads

Call Chain

Query

Maps To New Query

FieldDataCache.__init__() / FieldDataCache.add_descriptor_descendants()
FieldDataCache.add_descriptors_to_cache()
FieldDataCache._retrieve_fields()

return self._chunked_query(
StudentModule,
'module_state_key__in',
self._all_usage_ids(descriptors),
course_id=self.course_id,
student=self.user.pk,
)
Ultimately, an objects.filter() call.
 

Writes

Call Chain

Query

Maps To New Query
FieldDataCache.find_or_create()
DjangoKeyValueStore.set_many()

field_object = StudentModule(
course_id=self.course_id,
student_id=key.user_id,
module_state_key=key.block_scope_id,
state=json.dumps({}),
module_type=key.block_scope_id.block_type,
)

 
DjangoKeyValueStore.set_many()StudentModule.save() 

DjangoKeyValueStore.delete()

StudentModule.save()

 

lms/djangoapps/class_dashboard/dashboard_data.py

Reads

Call ChainQueryMaps To New Query

get_problem_grade_distribution()

db_query = models.StudentModule.objects.filter(
course_id__exact=course_id,
grade__isnull=False,
module_type__exact="problem",
).values(
'module_state_key', 'grade', 'max_grade'
).annotate(
count_grade=Count('grade')
)

 

get_sequential_open_distrib()

db_query = models.StudentModule.objects.filter(
course_id__exact=course_id,
module_type__exact="sequential",
).values(
'module_state_key'
).annotate(
count_sequential=Count('module_state_key')
)

 

get_problem_set_grade_distrib()

db_query = models.StudentModule.objects.filter(
course_id__exact=course_id,
grade__isnull=False,
module_type__exact="problem",
module_state_key__in=problem_set,
).values(
'module_state_key',
'grade',
'max_grade',
).annotate(
count_grade=Count('grade')
).order_by(
'module_state_key', 'grade'
)

 

get_students_opened_subsection()

students = models.StudentModule.objects.select_related('student').filter(
module_state_key__exact=module_state_key,
module_type__exact='sequential',
).values(
'student__username', 'student__profile__name'
).order_by(
'student__profile__name'
)

 

get_students_problem_grades()

students = models.StudentModule.objects.select_related('student').filter(
module_state_key=module_state_key,
module_type__exact='problem',
grade__isnull=False,
).values(
'student__username', 'student__profile__name', 'grade', 'max_grade'
).order_by(
'student__profile__name'
)

 

lms/djangoapps/courseware/grades.py

Reads

Call ChainQueryMaps to New Query

answer_distributions(course_key)

for module in StudentModule.all_submitted_problems_read_only(course_key):

...which is:

queryset = cls.objects.filter(
course_id=course_id,
module_type='problem',
grade__isnull=False
)
if "read_replica" in settings.DATABASES:
return queryset.using("read_replica")
else:
return queryset

 
_grade(student, request, course, keep_raw_scores)

should_grade_section = StudentModule.objects.filter(
student=student,
module_state_key__in=[
descriptor.location for descriptor in section['xmoduledescriptors']
]
).exists()

 

get_score(course_id, user, problem_descriptor,

module_creator, scores_cache=None)

student_module = StudentModule.objects.get(
student=user,
course_id=course_id,
module_state_key=problem_descriptor.location
)

 

common/djangoapps/xmodule_modifiers.py

This access behaves poorly - it accesses the CSM table via direct SQL!

Call ChainQueryMaps to New Query
grade_histogram()

SELECT courseware_studentmodule.grade,
COUNT(courseware_studentmodule.student_id)
FROM courseware_studentmodule
WHERE courseware_studentmodule.module_id=%s
GROUP BY courseware_studentmodule.grade

 

lms/djangoapps/courseware/entrance_exams.py

Determines a user's entrance exam score via direct CSM access.

Call ChainQueryMaps to New Query

_calculate_entrance_exam_score()

student_modules = StudentModule.objects.filter(
student=user,
course_id=course_descriptor.id,
module_state_key__in=exam_module_ids,
)

 

lms/djangoapps/courseware/views.py

Call ChainQueryMaps to New Query

submission_history(request, course_id,

student_username, location)

student_module = StudentModule.objects.get(
course_id=course_key,
module_state_key=usage_key,
student_id=student.id
)
history_entries = StudentModuleHistory.objects.filter(
student_module=student_module
).order_by('-id')

# If no history records exist, let's force a save to get history started.
if not history_entries:
student_module.save()
history_entries = StudentModuleHistory.objects.filter(
student_module=student_module
).order_by('-id')

 

lms/djangoapps/courseware/management/commands/clean_history.py

Django management command that clears CSM history for a particular student module.

Call ChainQueryMaps to New Query
get_last_student_module_id()SELECT max(student_module_id) FROM courseware_studentmodulehistory 
get_history_for_student_modules()

SELECT id, created FROM courseware_studentmodulehistory
WHERE student_module_id = %s
ORDER BY created, id

 
delete_history()

DELETE FROM courseware_studentmodulehistory
WHERE id IN ({ids})

 

lms/djangoapps/courseware/management/commands/regrade_partial.py

One-off Django management command.

Call ChainQueryMaps to New Query
fix_studentmodules()

modules = StudentModule.objects.filter(modified__gt='2013-03-07 20:18:00',
created__lt='2013-03-08 15:45:00',
state__contains='"npoints": 0.')

None - will be deleted.

lms/djangoapps/courseware/management/commands/remove_input_state.py

One-off Django management command.

Call ChainQueryMaps to New Query
fix_studentmodules_in_list()

module = StudentModule.objects.get(id=student_module_id)

hist_modules = StudentModuleHistory.objects.filter(student_module_id=student_module_id)

None - will be deleted.

lms/djangoapps/courseware/management/commands/tests/test_clean_history.py

Call ChainQueryMaps to New Query
From many tests: write_history()

INSERT INTO courseware_studentmodulehistory
(id, created, student_module_id)
VALUES (%s, %s, %s)

 
From many tests: read_history()

SELECT id, created, student_module_id FROM courseware_studentmodulehistory

 

lms/djangoapps/courseware/tests/test_model_data.py

Several tests perform direct StudentModule.object() access.

lms/djangoapps/courseware/tests/test_module_render.py

Two tests - test_xmodule_runtime_publish() & test_xmodule_runtime_publish_delete() - use direct StudentModule.objects() access.

lms/djangoapps/courseware/tests/test_submitting_problems.py

Several tests perform direct StudentModule.object() access.

lms/djangoapps/instructor/enrollment.py

Call ChainQueryMaps to New Query
reset_student_attempts()

module_to_reset = StudentModule.objects.get(
student_id=student.id,
course_id=course_id,
module_state_key=module_state_key
)

 Then .delete() or .save()

 

lms/djangoapps/instructor/management/commands/openended_stats.py

Call ChainQueryMaps to New Query
calculate_task_statistics()

student_modules = StudentModule.objects.filter(

module_state_key=location, student__in=students

).order_by('student')

 

lms/djangoapps/instructor/tests/test_api.py

Several tests perform direct StudentModule.object() access.

lms/djangoapps/instructor/tests/test_enrollment.py

Several tests perform direct StudentModule.object() access.

lms/djangoapps/instructor/tests/test_tools.py

Several tests perform direct StudentModule.object() access.

lms/djangoapps/instructor/views/legacy.py

Dumps CSV of problem reponses.

Call ChainQueryMaps to New Query
instructor_dashboard()

smdat = StudentModule.objects.filter(
course_id=course_key,
module_state_key=module_state_key
)
smdat = smdat.order_by('student')

 

lms/djangoapps/instructor/views/tools.py

Call ChainQueryMaps to New Query
get_extended_due(course, unit, student)

student_module = StudentModule.objects.get(
student_id=student.id,
course_id=course.id,
module_state_key=unit.location
)

 

set_due_date_extension(course, unit,

student, due_date)

student_module = StudentModule.objects.get(
student_id=student.id,
course_id=course.id,
module_state_key=node.location
)

Then .save()

or

student_module = StudentModule.objects.create(
student_id=student.id,
course_id=course.id,
module_state_key=node.location,
module_type=node.category
)

 
 dump_module_extensions(course, unit) query = StudentModule.objects.filter(

course_id=course.id,
module_state_key=unit.location)

 
dump_student_extensions(course, student)

query = StudentModule.objects.filter(
course_id=course.id,
student_id=student.id)

 

lms/djangoapps/instructor_task/tasks_helper.py

Call ChainQueryMaps to New Query
perform_module_state_update()

modules_to_update = StudentModule.objects.filter(

course_id=course_id, module_state_key__in=usage_keys

)

 

lms/djangoapps/instructor_task/tests/test_base.py

A test performs direct StudentModule.object() access.

lms/djangoapps/instructor_task/tests/test_tasks.py

Several tests perform direct StudentModule.object() access.

lms/djangoapps/psychometrics/models.py

Creates a model that joins with every single row in CSM. This functionality will likely not be possible with the CSM behind an interface!

Other associated files:

  • lms/djangoapps/psychometrics/psychoanalyze.py
  • lms/djangoapps/psychometrics/management/commands/init_psychometrics.py

src/edx-sga/edx_sga/sga.py

Staff-graded assignments XBlock.

Call ChainQueryMaps to New Query
staff_grading_data()

module, _ = StudentModule.objects.get_or_create(
course_id=self.course_id,
module_state_key=self.location,
student=user,
defaults={
'state': '{}',
'module_type': self.category,
})

 
staff_upload_annotated()

module = StudentModule.objects.get(pk=request.params['module_id'])

And finally, .save()

 
staff_download_annotated()

module = StudentModule.objects.get(pk=request.params['module_id'])

 
enter_grade()

module = StudentModule.objects.get(pk=request.params['module_id'])

And finally, .save()

 
remove_grade()

module = StudentModule.objects.get(pk=request.params['module_id'])

And finally, .save()

 

src/edx-sga/edx_sga/tests.py

Tests of staff-graded assignments XBlock.

Several tests perform direct StudentModule.object() access.

src/edx-sga/edx_sga/management/commands/sga_migrate_submissions.py

Django management command that migrates existing SGA submissions for a course from old SGA implementation to newer version that uses the 'submissions' application.

Call ChainQueryMaps to New Query
 

student_modules = StudentModule.objects.filter(
course_id=course.id).filter(
module_state_key__contains='edx_sga')

 
  • No labels