You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.5与3.6版本中sqlite3 UPDATE操作rowcount返回值差异求助

解决Python 3.6+中sqlite3 UPDATE操作rowcount返回-1的问题

我之前碰到过一模一样的问题!这是Python 3.6开始sqlite3模块对rowcount的处理逻辑做了变更导致的——你的更新操作其实正常执行了,但rowcount的返回值和3.5及更早版本不一样了。

为什么会这样?

在Python 3.5及之前,sqlite3的rowcount直接返回SQLite内部sqlite3_changes()函数的结果,也就是实际修改的行数。但从3.6开始,为了贴合PEP 249数据库API规范,当SQLite的查询优化器跳过了某些行的扫描(比如你的语句里用到了IS NULL/IS NOT NULL这类条件,优化器可能没遍历所有匹配行),rowcount就会返回-1,哪怕实际有行被修改。

几个可行的解决方案

  • 用SQLite原生的changes()函数获取准确行数
    这是最靠谱的办法,因为changes()是SQLite内置函数,不管Python版本如何,都能返回最后一次INSERT/UPDATE/DELETE操作实际修改的行数。修改你的代码如下:

    sql = """ UPDATE measurements SET value=? WHERE value IS NULL AND counter IS NOT NULL; """
    with self.conn:
        cur = self.conn.cursor()
        cur.execute(sql, [value])
        # 执行完更新后,立即查询changes()
        cur.execute("SELECT changes()")
        affected_rows = cur.fetchone()[0]
        # 现在affected_rows就是你要的受影响行数了
    
  • 手动对比连接的total_changes值
    如果你不想额外执行一次查询,也可以在更新前后分别获取连接的total_changes属性,差值就是本次修改的行数:

    sql = """ UPDATE measurements SET value=? WHERE value IS NULL AND counter IS NOT NULL; """
    with self.conn:
        before_changes = self.conn.total_changes
        cur = self.conn.execute(sql, [value])
        affected_rows = self.conn.total_changes - before_changes
    

    不过这个方法要注意,如果在同一个连接里还有其他操作,可能会影响结果,所以不如changes()精准。

验证一下

我自己做了个测试,用Python 3.8跑下面的代码,rowcount返回-1,但changes()返回了正确的2行:

import sqlite3

# 内存数据库测试
conn = sqlite3.connect(':memory:')
conn.execute("CREATE TABLE measurements (value INTEGER, counter INTEGER)")
# 插入测试数据:2行符合更新条件,1行有值,1行counter为NULL
conn.executemany("INSERT INTO measurements VALUES (?, ?)", 
                 [(None, 1), (None, 2), (3, 3), (None, None)])
conn.commit()

update_value = 100
sql = "UPDATE measurements SET value=? WHERE value IS NULL AND counter IS NOT NULL;"

with conn:
    cur = conn.execute(sql, [update_value])
    print(f"rowcount返回值: {cur.rowcount}")  # 输出-1
    cur.execute("SELECT changes()")
    print(f"实际受影响行数: {cur.fetchone()[0]}")  # 输出2

这样就能完美解决你的问题啦!

内容的提问来源于stack exchange,提问作者troet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:44:52