Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

lms/djangoapps/courseware/model_data.py

FieldDataCache is defined in this file - it's a cache of Django ORM objects from CSM. The object are read into the cache and then modified / written from the cache.

Reads

Call Chain

Query

R/W?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.
R 001 / 002

Writes

DjangoKeyValueStore
Call Chain

Query

R/W?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,
)

 W001 / 002
DjangoKeyValueStore.set_many()StudentModule.save()W 001 / 002

DjangoKeyValueStore.delete()

StudentModule.save()

W 001 / 002

lms/djangoapps/class_dashboard/dashboard_data.py

Reads

Call ChainQueryR/W?Maps 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')
)

R 010

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')
)

R 015

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'
)

 R012

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'
)

 R013

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'
)

R 011

lms/djangoapps/courseware/grades.py

Reads

Call ChainQueryR/W?Maps 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

R 006
_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()

R 

---

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
)

 R008

common/djangoapps/xmodule_modifiers.py

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

Call ChainQueryR/W?Maps 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

R

---

 

lms/djangoapps/courseware/entrance_exams.py

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

Call ChainQueryR/W?Maps 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,
)

 
R002

lms/djangoapps/courseware/views.py

Call ChainQueryR/W?Maps 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.

None - will be deleted.
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)

R/W

CSMH will likely become just another

column family. Possibly one like:

 

  Row key
<course|student|module> =>
 Column Name       Column Value
 <timestamp> : <JSON with version|created|state|grade|max_grade>

lms/djangoapps/courseware/management/commands

...

/

...

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.Django management command that clears CSM history for a particular student module.

Call ChainQueryR/W?Maps to New Query
get_last_student_module_id()SELECT max(student_module_id) FROM courseware_studentmodulehistoryRIf TTL used, this isn't necessary.
get_history_for_student_modules()

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

R(course, student, module, timestamp)
delete_history()

DELETE FROM courseware_studentmodulehistory
WHERE id IN ({ids})

WWe'll use TTL instead of explicit delete?

lms/djangoapps/courseware/

...

management/commands/

...

regrade_

...

partial.py

Two tests - test_xmodule_runtime_publish() & test_xmodule_runtime_publish_delete() - use direct StudentModule.objects() access.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

Several tests perform direct StudentModule.object() access.

...

One-off Django management command.

Call ChainQueryMaps to New Query
resetfix_studentmodules_studentin_attemptslist()

module _to_reset = StudentModule.objects.get(
student_id=student._module_id,)

coursehist_id=course_id,
module_state_key=module_state_key
)

 Then .delete() or .save()

 

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 Querycalculate_task_statistics()

student_modules = StudentModule.objects.filter(

module_state_key=location, student__in=students

).order_by('student')

QueryMaps 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

Several tests perform direct StudentModule.object() access.

lms/djangoapps/instructor/tests/test_enrollment.py

Several tests perform direct StudentModule.object() accessTwo 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 ChainQueryR/W?Maps to New Query
instructorreset_student_dashboardattempts()

smdat module_to_reset = StudentModule.objects.filterget(
student_id=student.id,
course_id=course_keyid,
module_state_key=module_state_key
) smdat = smdat.order_by('student')

 

 Then .delete() or .save()

RW001

lms/djangoapps/instructor/

...

management/commands/openended_stats.py

Call ChainQueryR/W?Maps to New Query
getcalculate_extendedtask_duestatistics(course, unit, student)

student_module modules = StudentModule.objects.getfilter( 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

module_state_key=location, student__in=students

).order_by('student')

R

007

(course, module, students)

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 ChainQueryR/W?Maps to New Query
instructor_dashboard()

smdat = StudentModule.objects.filter(
course_id=course.id_key,
module_state_key=unit.location)

 dump_student_extensions(course, student)

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

module_state_key
)
smdat = smdat.order_by('student')

R

None - who needs this?

Provide another inteface for it.


lms/djangoapps/instructor_task/tasks_helper.py

Call ChainQueryR/W?Maps to New Query
perform_module_state_update()

modules_to_update = StudentModule.objects.filter(

course_id=course_id, module_state_key__in=usage_keys

)

 

usage_keys

)

Also supports a further student and generic filter_fcn() filtering.

RW

001 / 004

BUT - support of generic filter_fcn()

probably not possible.

lms/djangoapps/instructor_task/tests/test_base.py

...

Staff-graded assignments XBlock.

Call ChainQueryR/W?Maps 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,
})

RW ---
staff_upload_annotated()

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

And finally, .save()

RW ---
staff_download_annotated()

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

 RW---
enter_grade()

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

And finally, .save()

RW ---
remove_grade()

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

And finally, .save()

 RW---

src/edx-sga/edx_sga/tests.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 ChainQueryR/W?Maps to New Query
 

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

R ---