SQLAlchemy使用〜和and_,or_

时间:2019-06-16 13:17:34

标签: python sqlalchemy

我有一个表情:

recent_oa = db_session.query(exists().where(
    and_(
        and_(Jobs.candidate_id == candidate_id, Jobs.interview_type == 'EVALUATION', Jobs.disposition_date < datetime.now()-timedelta(days=1)),
        ## I want this to evaluate to be True
        and_(~Jobs.candidate_id == candidate_id, Jobs.interview_type == 'IN_HOUSE', Jobs.disposition_date > '2017-01-01'),
        ## and I want this to evaluate to False    
    )
)).scalar()

recent_oa
>> True

以便recent_oa的评估结果为True

我想创建多个条件,如果第一行的评估结果为True,然后其余的行评估为False,则recent_oa的评估结果为{{1} }

我将如何编写该表达式?我的方式似乎不起作用。

1 个答案:

答案 0 :(得分:0)

您需要前缀您需要用~来求反的表达式,所以~ and_(...)

请注意,所有布尔逻辑运算符都有运算符和函数。 ~也可以作为not_() function使用,并且类似地,and_()可以用&表示,or_()可以用|表示。我会坚持一种或另一种,而不是两种。

因此您的要求可以表示为

and_(
    and_(
        Jobs.candidate_id == candidate_id,
        Jobs.interview_type == 'EVALUATION',
        Jobs.disposition_date < datetime.now()-timedelta(days=1)
    ),

    not_(
        and_(
            not_(Jobs.candidate_id == candidate_id),
            Jobs.interview_type == 'IN_HOUSE',
            Jobs.disposition_date > '2017-01-01'
        )
    )
)

或为

(
    (
        (Jobs.candidate_id == candidate_id)
        & (Jobs.interview_type == 'EVALUATION')
        & (Jobs.disposition_date < datetime.now()-timedelta(days=1))
    )

    & (
        ~ (
            ~ (Jobs.candidate_id == candidate_id)
            & (Jobs.interview_type == 'IN_HOUSE')
            & (Jobs.disposition_date > '2017-01-01')
        )
    )
)

由于~&|运算符具有lower precedence than comparison operators,因此您必须在上述每个测试周围使用(...)括号以确保运算符适用于整个column == valuecolumn < value测试。

我不是100%确定您要使用not_(Jobs.candidate_id == candidate_id),但是如果您这样做了,那么我只在这里使用!=,所以Jobs.candidate_id != candidate_id并放下{{1 }}测试的条件。

接下来,该查询可能始终无法给出正确的结果。它会告诉您是否有1或多行符合您的条件,因此候选人ID匹配的行以及面试类型和处置日期都有特定条件。它会做的是告诉您是否只有这样的行匹配。因此,如果有这样的行:

not_()

然后您将得到 candidate_id | disposition_date | interview_type ---------------|-------------------|----------------- 42 | 2018-01-01 | EVALUATION 42 | 2018-01-02 | IN_HOUSE ,因为有1行符合您的条件。 True行被过滤掉。您不会在这里得到IN_HOUSE,因为过滤器是否存在另一行无关紧要。

在这种情况下,您想在单独的False子句上使用NOT表达式布尔逻辑,不是条件,因此第二行的存在导致{ {1}}的结果针对另一行的EXISTS

False

因此创建两个单独的存在查询

True

这使用Query.exists() method来产生单独的SELECT id FROM jobs WHERE EXISTS(candidate_id = ? AND interview_type = ? AND disposition_date < ?) AND NOT EXISTS(candidate_id = ? AND interview_type = ? AND disposition_date > ?) 条件。