使用SQLAlchemy更新数据触发StaleDataError行数匹配错误的解决方案
问题描述
我尝试通过SQLAlchemy更新一行数据,遇到如下报错:
sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'ImgToolUser' expected to update 1 row(s); 2 were matched.
我执行的代码如下:
user = session.query(ImageToolUser).filter(ImageToolUser.key == key).first() user.name = 'changed' session.commit()
我查看sqlalchemy.engine日志,发现实际执行的UPDATE语句为:
UPDATE `ImgToolUser` SET maker=%(maker)s, effect=%(effect)s WHERE `ImgToolUser`.mail = %(ImgToolUser_mail)s
该语句通过ImgToolUser.mail字段过滤,而我的表中有2行记录的mail字段值相同,因此触发报错。但我自己写的查询逻辑是通过key字段过滤的,为什么实际更新时用mail作为过滤条件?应该如何修改代码才能正确更新目标行?
解决方案
问题根源是ImageToolUser映射类的主键设置错误,最初错误将mail字段设为了主键:
class ImageToolUser(Base): __tablename__ = "ImgToolUser" mail = Column(String(255), primary_key=True) name = Column(String(255)) key = Column(String(255))
SQLAlchemy更新ORM实例时默认会使用主键作为过滤条件,因为ORM默认主键是单条记录的唯一标识,和查询实例时使用的过滤条件无关。将主键改为全局唯一的key字段后问题解决:
class ImageToolUser(Base): __tablename__ = "ImgToolUser" mail = Column(String(255)) name = Column(String(255)) key = Column(String(255), primary_key=True)
希望这个解决方案能帮助到遇到同类问题的开发者。
内容的提问来源于stack exchange,提问作者Nori
相关产品推荐
相关产品推荐

