在 mssql 上更新记录时,SqlAlchemy StaleDataError 返回 -1

希德尼*_*的骑士 5 sql-server sqlalchemy rowcount

我用来flask-sqlalchemy更新mssql记录,但它返回-1。

库版本:

  1. SQLAlchemy 1.3.11
  2. Flask-SQLAlchemy 2.4.1
  3. pyodbc 4.0.27
  4. 烧瓶1.1.1

代码第 1 部分:

ret = db.session.query(XXX).filter_by(id=1).update({"xxx": "xxxx"})
print("ret", ret)
db.session.commit()
Run Code Online (Sandbox Code Playgroud)

ret-1,但记录已被修改。

代码第 2 部分:

obj = XXX.query.filter_by(id=q).first()
obj .xx = "xxx"
db.session.commit()
Run Code Online (Sandbox Code Playgroud)

引发错误:

sqlalchemy.orm.exc.StaleDataError: UPDATE statement on table 'XXX' expected to update 1 row(s); -1 were matched.
Run Code Online (Sandbox Code Playgroud)

而且修改没有成功。

tam*_*ama 3

根据 SQLAlchemy文档,目前某些版本的 SQL Server 驱动程序存在限制,无法返回 UPDATE 和 DELETE 语句的记录数。我目前在 Linux 上遇到了这个问题,但在 Windows 上工作正常。

这里还有一个相关的 SQL Alchemy 问题

我使用该列作为版本指示器(文档建议创建 SQLServer ROWVERSION 但是,SQLAlchemy/PyODBC,同样在 Linux 上,无法将数据库中的正确 FetchedValues() 作为字节分配到字段中。我还尝试使用 DateTime2字段 - 然而,当将字段映射到 Python 时,再次考虑 SQLAlchemy 的准确性(7 精度)

我最终实施了以下更改:

由于数据库已经分配了 ID 列 (IDENTITY),因此我使用该字段作为版本指示器。

    __mapper_args__ = {
        'version_id_col': id_column,
        'version_id_generator': False,
    }
Run Code Online (Sandbox Code Playgroud)

SQLAlchemy 更新语句现在如下所示:

UPDATE <TABLE> SET <column>=? OUTPUT inserted.<ID-COLUMN> WHERE <TABLE>.<ID-COLUMNS> <ID-COLUMN> = ? AND <TABLE>.<ID-COLUMN> = ?

[('updated data', 123456, 123456)]

Run Code Online (Sandbox Code Playgroud)