[英]Bulk update with subquery using SQLAlchemy
我正在嘗試使用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')
...我得到InvalidRequestError: This operation requires only one Table or entity be specified as the target
。 在我看來, Category.depth
充分指定了目標,但當然SQLAlchemy勝過我的想法。
難住了。 有什么建議? 謝謝。
我知道這個問題已有五年了,但我今天偶然發現了它。 我的回答可能對其他人有用。 我知道我的解決方案並不完美,但我沒有更好的方法。
我不得不將最后一行更改為:
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()
這給出了以下警告:
SAWarning:在ORM實例上評估非映射列表達式“...”; 這是一個棄用的用例。 請使用ORM評估的UPDATE / DELETE表達式中的實際映射列。
“UPDATE / DELETE表達式。” %子句
為了擺脫它,我在這篇文章中使用了解決方案: 在sqlalchemy中關閉警告
注意:由於某些原因,別名在SQLAlchemy更新語句中不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.