sqlalchemy применяет фильтр только если значение не None - PullRequest
0 голосов
/ 21 апреля 2020

Я работаю над созданием фильтра sqlalchemy, который ищет строки между указанным c временным диапазоном, но я хочу, чтобы этот фильтр применялся, только если у них есть значение для дня. Если они этого не делают, они также должны быть возвращены. Фильтр выглядит следующим образом:

 models = {
        CheckinAction: Student.person_id == CheckinAction.person_id,
        CheckinTimeRange: CheckinAction.chk_checkin_time_range_id == CheckinTimeRange.pk,
    }

    return join_models(query, models, "outerjoin").filter(
        CheckinTimeRange.day >= pendulum.parse(start_day).date(), CheckinTimeRange.day <= pendulum.parse(end_day).date()
    )

В приведенном выше коде модели CheckinAction и CheckinTimeRange подключаются к существующему запросу Student. Я бы хотел применить фильтр CheckinTimeRange.day только в том случае, если у них есть действие для регистрации. Примером может быть:

row #1: {
student_id = 1,
student_name = 'row_to_not_filter',
checkin_action = None,
checkin_time_range = None
}

row #2: {
student_id = 2,
student_name = 'row_to_filter',
checkin_action = some_object,
checkin_time_range = {day = '2020-04-21'}
}

Я бы хотел применить фильтр только ко второй строке, потому что у них есть checkin_time_range.

1 Ответ

1 голос
/ 21 апреля 2020

Поскольку вы используете LEFT JOIN, переместите предикат в предложение ON в объединении:

from sqlalchemy import and_

...
    models = {
        CheckinAction: Student.person_id == CheckinAction.person_id,
        CheckinTimeRange: and_(
            CheckinAction.chk_checkin_time_range_id == CheckinTimeRange.pk,
            CheckinTimeRange.day >= pendulum.parse(start_day).date(),
            CheckinTimeRange.day <= pendulum.parse(end_day).date()
        )
    }

    return join_models(query, models, "outerjoin")

Поскольку CheckinAction.chk_checkin_time_range_id используется в предложении ON объединения в CheckinTimeRange, AND оценивается как NULL для строки 1 и, таким образом, достигает результата без учета временного диапазона, если действие отсутствует. Перемещение предиката диапазона в предложение ON также обеспечивает включение в результаты строк без диапазона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...