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

1 投票
2 回答
1240 浏览
提问于 2025-04-17 13:56

我有一个表格,里面有一列叫做 region_code,它的数据类型是 Integer(整数)。在我的Python程序中,有这样一行代码:

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

这里最重要的是选择的 filter 方法

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(微软的数据库)中,这样做是完全没问题的。


但不幸的是(在我的情况下),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

为什么不在你的Python脚本中单独进行除法运算,把结果保存到一个变量里,然后在查询中使用这个变量,而不是直接在查询中进行运算呢?

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)

撰写回答