SQLAlchemy 无缘无故在子查询末尾添加“=1”
SQLAlchemy adds "=1" to the end of subqueries for no reason
我正在尝试 运行 子查询,然后根据与该子查询的匹配进行更新。输出 SQL 一切正常,除了 SQLAlchemy 似乎无缘无故地将“=1”添加到我的子查询的末尾,这使得更新命中 0 行。这是代码:
to_update = session.query(DSI.id)\
.join(TB)\
.join(TBC)\
.join(TBCTD)\
.filter(func.DATE(TBCTD.dt)
== func.subdate(func.current_date(), 2))\
.filter(DSI.score > 110)\
.group_by(func.DATE(TBCTD.dt),
DSI.name, DSI.a_id)\
.having(func.sum(
TBCTD.num_things
> 100)).subquery()
session.query(DSI).filter(DSI.id == to_update.c.id)\
.update({"some_num": DSI.some_num*.98})
由此吐出的MYSQL长这样:
UPDATE dsis, (SELECT dsis.id AS id
FROM dsis
INNER JOIN tbs ON tbs.id = dsis.a_id
INNER JOIN tbcs ON tbs.id = tbcs.a_id
INNER JOIN tbctds ON tbcs.id = tbctds.tbcs_id
WHERE DATE(tbctds.dt) = subdate(CURRENT_DATE, %s)
AND dsis.score > %s
GROUP BY DATE(tbctds.dt), dsis.name, dsis.a_id
HAVING sum(tbctds.num_things > %s) = 1)
AS anon_1
SET dsis.some_num=(dsis.some_num * %s)
WHERE dsis.id = anon_1.id
2015-02-20 21:11:53,164 INFO sqlalchemy.engine.base.Engine (2, 110, 100, 0.98)
如您所见,一个额外的“= 1”完全没有理由地附加到子查询的末尾,我也不知道。我试过用几种方法重写语句,但总是遇到同样的问题。
你应该写
having(func.sum(TBCTD.num_things) > 100)
测试 sum()
是否大于 100。而不是你写
having(func.sum(TBCTD.num_things > 100))
这将对布尔值求和(这又是 TINYINT(1)
.
有趣的是,整数为true是-1,false是0;所以你会以一个非正整数结尾); SQLAlchemy 知道它需要 having
的布尔值,因此它尝试通过将它与 1
进行比较来测试它的真实性;毕竟 -1
的 TINYINT(1)
将等于 MySQL 中的 1
因为 1
作为常量被强制到 TINYINT(1)
的范围.
但是在您的情况下,HAVING
子句 永远不会 为真,因为结果不是布尔值,也不是正数。
我正在尝试 运行 子查询,然后根据与该子查询的匹配进行更新。输出 SQL 一切正常,除了 SQLAlchemy 似乎无缘无故地将“=1”添加到我的子查询的末尾,这使得更新命中 0 行。这是代码:
to_update = session.query(DSI.id)\
.join(TB)\
.join(TBC)\
.join(TBCTD)\
.filter(func.DATE(TBCTD.dt)
== func.subdate(func.current_date(), 2))\
.filter(DSI.score > 110)\
.group_by(func.DATE(TBCTD.dt),
DSI.name, DSI.a_id)\
.having(func.sum(
TBCTD.num_things
> 100)).subquery()
session.query(DSI).filter(DSI.id == to_update.c.id)\
.update({"some_num": DSI.some_num*.98})
由此吐出的MYSQL长这样:
UPDATE dsis, (SELECT dsis.id AS id
FROM dsis
INNER JOIN tbs ON tbs.id = dsis.a_id
INNER JOIN tbcs ON tbs.id = tbcs.a_id
INNER JOIN tbctds ON tbcs.id = tbctds.tbcs_id
WHERE DATE(tbctds.dt) = subdate(CURRENT_DATE, %s)
AND dsis.score > %s
GROUP BY DATE(tbctds.dt), dsis.name, dsis.a_id
HAVING sum(tbctds.num_things > %s) = 1)
AS anon_1
SET dsis.some_num=(dsis.some_num * %s)
WHERE dsis.id = anon_1.id
2015-02-20 21:11:53,164 INFO sqlalchemy.engine.base.Engine (2, 110, 100, 0.98)
如您所见,一个额外的“= 1”完全没有理由地附加到子查询的末尾,我也不知道。我试过用几种方法重写语句,但总是遇到同样的问题。
你应该写
having(func.sum(TBCTD.num_things) > 100)
测试 sum()
是否大于 100。而不是你写
having(func.sum(TBCTD.num_things > 100))
这将对布尔值求和(这又是 TINYINT(1)
.
有趣的是,整数为true是-1,false是0;所以你会以一个非正整数结尾); SQLAlchemy 知道它需要 having
的布尔值,因此它尝试通过将它与 1
进行比较来测试它的真实性;毕竟 -1
的 TINYINT(1)
将等于 MySQL 中的 1
因为 1
作为常量被强制到 TINYINT(1)
的范围.
但是在您的情况下,HAVING
子句 永远不会 为真,因为结果不是布尔值,也不是正数。