从psycopg2的connection.commit()获取受影响的行数

68 投票
1 回答
62002 浏览
提问于 2025-04-18 11:15

目前,我有一个方法可以使用 psycopg2Python 中执行插入、更新和删除的操作:

def exec_statement(_cxn, _stmt):
    try:
        db_crsr = _cxn.cursor()
        db_crsr.execute(_stmt)
        _cxn.commit()
        db_crsr.close()
        return True
    except:
        return False

但我真正想要的是,不是返回一个布尔值,而是返回受事务影响的行数,如果操作失败则返回 -1。

有没有办法获取 _cxn.commit() 影响的行数呢?比如,对于单个插入操作,影响的行数总是 1;而对于删除或更新操作,则是受该语句影响的行数等等?

1 个回答

119

commit() 这个方法不能用来获取受影响的行数,但你可以在每次调用 execute 之后,通过 cursor 来获取这个信息。你可以使用它的 rowcount 属性来查看 SELECTINSERTUPDATEDELETE 操作影响了多少行。

也就是说:

    db_crsr = _cxn.cursor()
    db_crsr.execute(_stmt)

    rowcount = db_crsr.rowcount

    _cxn.commit()
    db_crsr.close()

    return rowcount

如果你想返回受影响的行数,我建议不要捕捉任何异常,因为如果操作真的失败了(比如查询语句写错了,或者违反了外键约束等等),应该抛出一个异常,这样调用者就可以捕捉到这个异常并做出相应的处理。(或者,如果你想集中处理异常,可以抛出一个自定义的 MyPostgresException,或者类似的东西。)

在某些情况下,非失败的情况下可能会返回 -1 (https://www.psycopg.org/docs/cursor.html#cursor.rowcount),所以我建议不要把这个值当作失败的标志。如果你真的想在失败的情况下返回一个数字,或许返回 -10 这样的数字会比较合适(在 except 块中),因为 rowcount 不应该返回这个值。

撰写回答