我正在尝试使用SQLAlchemy实现以下MySQL查询。有问题的表是嵌套集层次结构。
UPDATE category
JOIN
(
SELECT
node.cat_id,
(COUNT(parent.cat_id) - 1) AS depth
FROM category AS node, category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.cat_id
) AS depths
ON category.cat_id = depths.cat_id
SET category.depth = depths.depth
这很好用。
这就是我开始拔头发的地方:
from sqlalchemy.orm import aliased
from sqlalchemy import func
from myapp.db import db
node = aliased(Category)
parent = aliased(Category)
stmt = db.session.query(node.cat_id,
func.count(parent.cat_id).label('depth_'))
.filter(node.lft.between(parent.lft, parent.rgt))
.group_by(node.cat_id).subquery()
db.session.query(Category,
stmt.c.cat_id,
stmt.c.depth_)
.outerjoin(stmt,
Category.cat_id == stmt.c.cat_id)
.update({Category.depth: stmt.c.depth_},
synchronize_session='fetch')
得到CCD_ 1。在我看来,Category.depth
充分地指定了目标,但当然SQLAlchemy胜过了我的想法。
Stumped。有什么建议吗?谢谢
我知道这个问题已经五年了,但今天我偶然发现了它。我的回答可能对其他人有用。我知道我的解决方案并不完美,但我没有更好的方法来做到这一点。
我只能把最后一行改成:
db.session.query(Category)
.outerjoin(stmt,
Category.cat_id == stmt.c.cat_id)
.update({Category.depth: stmt.c.depth_},
synchronize_session='fetch')
然后,您必须提交更改:
db.session.commit()
这会发出以下警告:
SA警告:正在计算未映射的列表达式"…"到ORM实例;这是一个不推荐使用的用例。请使用ORM计算的UPDATE/DELETE表达式中的实际映射列
"UPDATE/DELETE表达式。"%子句
为了消除它,我在这篇文章中使用了解决方案:关闭sqlalchemy 中的警告
注意:由于某些原因,别名在SQLAlchemy更新语句中不起作用。