簡體   English   中英

使用SQLAlchemy使用子查詢批量更新

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM