SQLAlchemy执行PostgreSQL ltree节点更新操作结果与预期不符
问题根因分析
- 偏移量计算错误
原UPDATE语句中使用subpath(path, nlevel(:old_path) - 1)截取路径,多减了1位偏移。以你提到的场景为例:old_path为root.parent,层级数为2,从偏移1的位置截取会保留old_path的最后一段parent,和新路径parent拼接后就得到了你遇到的错误结果parent.parent。正确逻辑应该从偏移等于old_path层级数的位置开始截取,直接切掉完整的old_path前缀。 - 节点修改顺序错误
你在执行UPDATE语句前先修改了内存中db_object.path的值,而UPDATE语句的WHERE条件会命中所有路径前缀匹配old_path的节点,包括当前移动的节点本身,相当于该节点会被UPDATE语句二次修改,最终数据库值会覆盖你之前赋值的正确路径,同时内存中对象状态和数据库也会不一致。
修复方案
直接修改move_to函数即可,修正偏移量、移除提前修改节点路径的逻辑,执行更新后刷新对象状态同步数据库结果:
def move_to(db_object, old_path, new_path, session): update_descendants_query = f""" UPDATE {db_object.__tablename__} SET path = :new_path || subpath(path, nlevel(:old_path)) WHERE path <@ :old_path; """ session.execute( update_descendants_query, {"new_path": str(new_path), "old_path": str(old_path)} ) # 同步数据库更新结果到内存对象 session.refresh(db_object)
内容的提问来源于stack exchange,提问作者ggirodda
相关产品推荐
相关产品推荐

