SQLAlchemy ORM模式update方法SAWarning警告问题求助
解决SQLAlchemy ORM Update子查询触发SAWarning的问题
嘿,我明白你遇到的这个警告问题了!这个SAWarning是因为你用ORM的Query.update()方法时,直接引用了子查询的列(stmt.c.value1、stmt.c.value2),而ORM的这个update方法更适合处理映射实体本身的属性,对于子查询这类Core层面的表达式,它会认为是过时的用法。
解决方法:改用SQLAlchemy Core的update()构造器
我们可以切换到Core的update语句,配合session.execute()来执行,这样既能实现你的子查询更新需求,又能完美规避警告。
修改后的完整代码
from sqlalchemy import create_engine, Column, Integer, Float, Boolean, update from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import Session Base = declarative_base() engine = create_engine('postgresql+psycopg2://urldb', echo=True) session = Session(engine) class User1(Base): __tablename__ = 'user1' index = Column(Integer, primary_key=True) value1 = Column(Float) value2 = Column(Boolean) class User2(Base): __tablename__ = 'user2' index = Column(Integer, primary_key=True) value1 = Column(Float) value2 = Column(Boolean) try: User1.__table__.drop(engine) User2.__table__.drop(engine) Base.metadata.create_all(engine) except: Base.metadata.create_all(engine) user1 = User1(value1=12, value2=True) user2 = User1(value1=15, value2=True) user3 = User1(value1=7, value2=True) user4 = User2(value1=12, value2=True) user5 = User2(value1=15, value2=False) session.add_all([user1, user2, user3, user4, user5]) session.commit() # 构造子查询,只选择需要的列 subq = session.query(User2.value1, User2.value2).filter(User2.value1 > 12).subquery() # 使用Core的update构造器创建更新语句 update_stmt = update(User1).\ where(User1.value1 == subq.c.value1).\ values(value2=subq.c.value2) # 执行更新并提交 session.execute(update_stmt) session.commit()
关键说明
- 导入
update构造器:从sqlalchemy库中导入Core的update工具,这是处理复杂更新(比如子查询关联)的推荐方式。 - 优化子查询:子查询只选择我们需要的
value1和value2列,避免不必要的数据查询。 - Core Update语句:用
update(User1)指定要更新的表,通过where关联子查询,values设置要更新的字段,这样的写法完全符合SQLAlchemy的设计规范,不会触发警告。 - 执行方式:用
session.execute()执行Core语句,这是ORM中执行Core操作的标准方式,兼顾了Core的灵活性和ORM的会话管理。
这样修改后,你的更新逻辑会正常执行(user2的value2依然会被更新为False),同时那个烦人的SAWarning也会消失啦!
内容的提问来源于stack exchange,提问作者P Bouillon
相关产品推荐
相关产品推荐

