Ejemplo n.º 1
0
def make_single_query(course_id, query, associate_group=None, origin=QueryOrigin.WIDGET):
    """
    Make a single query for student information
    """
    temp_query = TemporaryQuery(
        inclusion=INCLUSION_MAP.get(query.inclusion),
        course_id=course_id,
        module_state_key=query.entity_id,
        filter_on=query.filter,
        entity_name=query.entity_name,
        query_type=query.query_type,
        origin=QUERYORIGIN_MAP[origin],
        done=False,
    )
    temp_query.save()
    try:
        if query.query_type == QueryType.SECTION:
            students = get_section_users(course_id, query)
        else:
            students = get_problem_users(course_id, query)
        bulk_queries = []
        for student_id, dummy0 in students:
            row = StudentsForQuery(
                query=temp_query,
                inclusion=INCLUSION_MAP[query.inclusion],
                student=User.objects.filter(id=student_id)[0],
            )
            bulk_queries.append(row)
        StudentsForQuery.objects.bulk_create(bulk_queries)
        TemporaryQuery.objects.filter(id=temp_query.id).update(done=True)  # pylint: disable=no-member
        if associate_group is not None:
            grouped_temp = GroupedTempQueryForSubquery(
                grouped_id=associate_group, query_id=temp_query.id  # pylint: disable=no-member
            )
            grouped_temp.save()

    except Exception as error:
        TemporaryQuery.objects.filter(id=temp_query.id).update(done=None)  # pylint: disable=no-member
        raise (error)

    # on roughly every 5th query, purge the temporary queries of anything older than
    rand = random.random()
    if rand > 0.8:
        purge_temporary_queries()
Ejemplo n.º 2
0
def make_existing_query(course_id, existing_queries):
    """
    Aggregates single queries in a group into one unified set of students
    """

    if existing_queries is None or len(existing_queries) == 0:
        return None

    ids_in_course = CourseEnrollment.objects.filter(course_id=course_id,
                                                    is_active=1,
                                                    ).values_list(DatabaseFields.USER_ID)
    query = User.objects.filter(id__in=ids_in_course)
    query_dct = defaultdict(list)

    for existing_query in existing_queries:
        if existing_query == "" or existing_query == QueryStatus.WORKING:
            continue
        inclusion_type = TemporaryQuery.objects.filter(id=existing_query)
        filtered_query = StudentsForQuery.objects.filter(query_id=existing_query).values_list(
            DatabaseFields.STUDENT_ID,
            flat=True,
        )
        if inclusion_type.exists():
            query_dct[inclusion_type[0].inclusion].append(filtered_query)

    for not_query in query_dct[INCLUSION_MAP.get(Inclusion.NOT)]:
        query = query.exclude(id__in=not_query)

    for and_query in query_dct[INCLUSION_MAP.get(Inclusion.AND)]:
        query = query.filter(id__in=and_query)

    or_query = User.objects.filter(id__in=ids_in_course)
    qobjs = Q()
    for orq in query_dct[INCLUSION_MAP.get(Inclusion.OR)]:
        qobjs = qobjs | (Q(id__in=orq))

    # if there are only or queries, return the or_query
    if len(query_dct[INCLUSION_MAP.get(Inclusion.NOT)]) == 0 and len(query_dct[INCLUSION_MAP.get(Inclusion.AND)]) == 0:
        return or_query.filter(qobjs)
    # if there is no or_query, do not include it as it contains all the students in the course
    elif len(query_dct[INCLUSION_MAP.get(Inclusion.OR)]) == 0:
        return query
    else:
        return query | or_query.filter(qobjs)