python - Sqlalchemy 使用 ~ 和 and_, or_
问题描述
我有一个表达:
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
则评估为True
我该怎么写这个表达式?我的方式似乎不起作用。
解决方案
您需要在需要反转的表达式前面加上~
, 所以~ and_(...)
.
请注意,所有布尔逻辑运算符都有运算符和函数。~
也可用作not_()
函数,类似地,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')
)
)
)
因为~
, &
and|
运算符的优先级低于比较运算符,所以您必须(...)
在上面的每个测试周围使用括号,以确保运算符适用于整个column == value
和column < value
测试。
我不是 100% 确定你打算使用not_(Jobs.candidate_id == candidate_id)
,但如果你这样做了,那么我就在!=
那里使用,所以Jobs.candidate_id != candidate_id
并放弃该not_()
测试的条件。
接下来,查询可能无论如何都不会给出正确的结果。它会告诉您是否有 1 行或更多行符合您的条件,即候选人 ID 匹配的行,以及面试类型和处置日期的特定条件。它不会告诉你是否只有这样的行匹配。所以如果有这样的行:
candidate_id | disposition_date | interview_type
---------------|-------------------|-----------------
42 | 2018-01-01 | EVALUATION
42 | 2018-01-02 | IN_HOUSE
那么你会得到True
,因为有 1 行符合你的条件。该IN_HOUSE
行被过滤掉。您不会到达False
这里,因为过滤器中存在另一行并不重要。
在这种情况下,您想在单独的子句上使用NOT
表达式布尔逻辑,而不是条件,因此第二行的存在会导致结果与另一行相反:EXISTS
False
True
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 > ?)
所以创建两个单独的存在查询:
candidate = db_session.query(Jobs).filter(Jobs.candidate_id == candidate_id)
has_evaluation = (
candidate
.filter(Jobs.interview_type == 'EVALUATION')
.filter(Jobs.disposition_date < datetime.now() - timedelta(days=1))
)
has_inhouse = (
candidate
.filter(Jobs.interview_type == 'IN_HOUSE')
.filter(Jobs.disposition_date > '2017-01-01')
)
recent_oa = (
db_session.query(Jobs.id)
.filter(has_evaluation.exists())
.filter(not_(has_inhouse.exists())) # or .filter(~has_inhouse.exists())
.scalar()
)
这使用产生分离条件的Query.exists()
方法。EXISTS
推荐阅读
- javascript - 无法在节点js中显示背景图片
- r - 以矢量格式从 R 导出图像,文本和绘图具有单独的图层?
- numpy - 张量点混乱
- java - 为什么我的代码会产生这个意外错误?
- apache-nifi - 刷新 PutSFTP 流文件结果?
- matlab - Matlab - 将零极点增益转换为传递函数(zp2tf)无法按预期工作
- nlp - 为什么语言模型中的“添加一个平滑”不计入分母
- android - 启用 StrictMode(检测全部)的 Crashlytics 给出“检测到未标记的套接字”
- jackson - 如何配置 Jackson 在 Micronaut 中使用 SNAKE_CASE?
- javascript - 如何将 Jison 包含到 Angular 中?