在SQLAlchemy中链接比较

Python支持链式比较: 1 < 2 < 3转换为(1 < 2) and (2 < 3)

我正在尝试使用SQLAlchemy进行SQL查询,如下所示:

results = session.query(Couple).filter(10 < Couple.NumOfResults < 20).all()

我得到的结果并不如预期。 我已经将引擎的echo=True关键字转换成了,实际上 - 生成的SQL查询只包含两个比较中的一个。

我找不到任何明确表示这是禁止的文档。 我认为如果Python中支持这种类型的表达式,它也应该在SQLAlchemy中支持。

为什么这不起作用? 我有一个可能的解决方案(分享答案),但很乐意听到其他意见。


SQLAlchemy不支持Python的链式比较。 以下是作者Michael Bayer的正式原因:

不幸的是,从python的角度来看这可能是不可能的。 “x <y <z”的机制依赖于两个单独表达式的返回值。 SQLA表达式(例如“column <5”)会返回一个BinaryExpression对象,其计算结果为True - 因此第二个表达式从不会被调用,因此我们永远不会有机会检测到表达式链。 此外,需要检测表达式链并将其转换为BETWEEN,因为SQL不支持链式比较运算符。 不包括chain-> BETWEEN部分的检测,为了进行这项工作,需要根据比较运算符的方向操作BinaryExpression对象的__nonzero__()值,以强制进行比较。 将一个基本的__nonzero__()添加到返回False的BinaryExpression中,说明当前代码库对它的容忍性很差,并且至少有很多“if x:”类型的检查将被转换为“if x is None: “,但可能会有更多难以解决的问题。 对于外部世界来说,它可能会造成严重破坏。 鉴于这里适当的SQL运算符是BETWEEN,它可以从运算符之间轻松访问,我不认为向后弯曲和混淆人员的水平是值得的,所以这是一个“wontfix”。

详情请参阅:https://bitbucket.org/zzzeek/sqlalchemy/issues/1394/sql-expressions-dont-support-x-col-y


原因可能是Python实际评估这个表达式:

(10 < Couple.NumOfResults and Couple.NumOfResults < 20)

and运算符在SQLAlchemy中不受支持(应使用and_代替)。 因此,链式比较在SQLAlchemy中是不允许的。

在原始示例中,应该编写此代码:

results = session.query(Couple).filter(and_(10 < Couple.NumOfResults, 
                                            Couple.NumOfResults < 20).all()
链接地址: http://www.djcxy.com/p/63523.html

上一篇: Chained comparisons in SQLAlchemy

下一篇: Android: Converting a Bitmap to a Monochrome Bitmap (1 Bit per Pixel)