使用SQLAlchemy更新后,如何通过returning获取计算字段新值?
解决SQLAlchemy异步ORM中Computed字段更新后会话内值不刷新的问题
问题根源
SQLAlchemy的会话(Session)会缓存实例对象,Computed类型的计算字段默认不会自动同步数据库更新后的新值——哪怕用returning子句返回了数据,ORM也可能没把新值更新到缓存的实例上,导致同会话内不管怎么查,读的都是旧缓存数据,只有新开会话才会重新从数据库拉取最新值。
具体解决办法
1. 显式返回Computed字段并手动同步实例
更新操作时,把total_cost明确加入returning子句,拿到返回的新数据后,手动覆盖会话缓存实例的对应属性:
from sqlalchemy import update # 执行更新,指定返回需要的字段 result = await session.execute( update(Tablichka) .where(Tablichka.id == target_id) .values(quantity=15, price=25) .returning(Tablichka.id, Tablichka.quantity, Tablichka.price, Tablichka.total_cost) ) updated_data = result.one() # 从会话中获取实例,同步新值 target_instance = await session.get(Tablichka, updated_data.id) target_instance.quantity = updated_data.quantity target_instance.price = updated_data.price target_instance.total_cost = updated_data.total_cost
2. 用Session.refresh()强制从数据库同步
更新完成后,调用session.refresh()方法,强制ORM从数据库重新加载实例的所有属性,包括Computed字段:
# 执行更新操作 await session.execute( update(Tablichka) .where(Tablichka.id == target_id) .values(quantity=15, price=25) ) await session.commit() # 获取实例并强制刷新 target_instance = await session.get(Tablichka, target_id) await session.refresh(target_instance) # 此时target_instance.total_cost就是数据库里的最新值
如果是在未提交的事务中,refresh()也能读取到数据库中未提交的修改(具体取决于数据库的隔离级别)。
3. 给Computed字段配置onupdate自动计算
定义模型时,给total_cost字段添加onupdate参数,指定当依赖的quantity或price更新时,自动计算并更新内存中的total_cost值:
from sqlalchemy import Column, Integer, Numeric, Computed class Tablichka(Base): __tablename__ = "tablichka" id = Column(Integer, primary_key=True) quantity = Column(Integer) price = Column(Numeric(10, 2)) total_cost = Column( Numeric(10, 2), Computed("quantity * price"), onupdate=lambda ctx: ctx.current_parameters.get("quantity") * ctx.current_parameters.get("price") )
这样更新quantity或price时,ORM会自动同步total_cost的内存值,不用额外手动操作。
4. 临时禁用实例缓存(仅调试用)
如果只是临时调试,可以在查询时用populate_existing(),强制忽略会话缓存,直接从数据库读最新数据:
target_instance = await session.query(Tablichka).filter_by(id=target_id).populate_existing().one()
不推荐长期用这个方法,会影响ORM的缓存性能。
内容的提问来源于stack exchange,提问作者Александр Десятов
相关产品推荐
相关产品推荐

