MySQL和SQLAlchemy WHERE子句中的整数转换

时间:2013-01-28 13:04:08

标签: python mysql sqlalchemy

我有一个表,其中包含一个名为region_code的列,其中Integer为其数据类型。在我的Python程序中,我有这一行:

region = session.query(Region).filter(Region.region_code/100 == region_prefix).one()

这里重要的部分是选择的过滤器方法

Region.region_code/100 == region_prefix

其中region_code是表中的整数列,region_prefix变量包含整数值

region_code是表中包含1199, 1200, 1300, 1499等值的整数列,而region_prefix变量(来自程序)包含11, 12, 13, 14之类的整数值。

我现在想要使用此过滤器选项实现的是对region_code执行整数除法(因此减少小数点后面的所有内容),以便能够将其与region_prefix进行比较。


示例:

region_prefix = 11

假设Region表中存在一个带

的条目
region_code = 1199

过滤器内的计算应该如下所示

1199 / 100 = 11

因此,通过此结果,我可以过滤region_prefix (11=11)这适用于MSSQL(Microsoft)。


不幸的是(在我的情况下) MySQL 除法运算符/不执行整数除法。因此1199/100的结果将为11.99,因此我的查询将无法在数据库中找到适合的条目(因为11.99!= 11)。 然而,MySQL实际上实现了内部划分: DIV 运算符。

所以下面的SQL查询对我来说很合适:

SELECT * FROM Region where region_code DIV 100 = 11;


所以我的问题是: 如何让SQLAlchemy filter方法使用DIV而不是/运算符?这可能吗?或者是使用本机查询的唯一解决方法?

2 个答案:

答案 0 :(得分:3)

幸运的是,SQLAlchemy允许自定义运算符。有很简单的方法可以执行此操作(只需在查询中指定)或执行此操作的更复杂版本(完全定义新运算符并使其具有多数据库感知能力)。所以这取决于你在寻找什么。

http://docs.sqlalchemy.org/en/latest/core/custom_types.html?highlight=operators#redefining-and-creating-new-operators

region = (session
    .query(Region)
    .filter(Region.region_code.op('div')(region_prefix))
    .one()
)

和奇特的方式:

http://docs.sqlalchemy.org/en/rel_0_8/core/types.html#types-operators

from sqlalchemy import Integer

class DivisibleInteger(Integer):
    class comparator_factory(Integer.Comparator):
        def div(self, other):
            return self.op('div')(other)

答案 1 :(得分:0)

为什么不在python脚本中单独执行除法运算,将结果保存到变量,然后在查询中传递变量而不是操作?