【问题标题】:Getting affected row count from psycopg2 connection.commit()从 psycopg2 connection.commit() 获取受影响的行数
【发布时间】:2014-06-26 22:17:43
【问题描述】:

目前,我有以下方法可以在Python 中使用psycopg2 执行INSERT/UPDATE/DELETE 语句:

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

但我真正希望它做的不是 bool,而是返回受事务影响的行数,如果操作失败则返回 -1。

有没有办法获得受_cxn.commit() 影响的行数?例如。对于单个 INSERT,它始终为 1,对于 DELETE 或 UPDATE,受语句影响的行数等?

【问题讨论】:

  • 不要使用裸露的except 子句!您应该使用psycopg2.errors 模块。 docs中有一个完整的列表

标签: python psycopg2


【解决方案1】:

commit() 不能用于获取行数,但您可以在每次 execute 调用后使用 cursor 获取该信息。您可以使用其rowcount 属性来获取SELECTINSERTUPDATEDELETE 受影响的行数。

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

    rowcount = db_crsr.rowcount

    _cxn.commit()
    db_crsr.close()

    return rowcount

如果您想返回受影响的行数,我建议不要捕获任何异常,因为如果操作确实失败(例如查询格式错误,或者违反 FK 约束等),则应该出现异常被提出,在这种情况下,调用者可以捕捉到它并按预期行事。 (或者,如果您想集中处理异常,可能是 raise 自定义 MyPostgresException 或类似的。)

-1 可以在某些情况下(http://initd.org/psycopg/docs/cursor.html#cursor.rowcount)在非失败情况下返回,因此我建议不要使用该值作为失败指示符。如果你真的想在失败的情况下返回一个数值,也许返回一个像 -10 这样的数字会起作用(在except 块中),因为rowcount 不应该返回那个。

【讨论】:

  • 您给出了不捕获异常的充分理由,但是有没有理由 db_crsr.close() 不在 finally 块中?它将在方法结束时超出范围。
  • @jpmc26:不。那是来自 OP 的原始代码,我并不专注于这方面。在这种特殊情况下,我实际上可能会在 with 块中声明 cursor 以便它会自动关闭。
  • 愚蠢的我。忘记with。 =) 我的生活中需要更多的 Python。
  • @jpmc26: =) 是的,这几乎是完美的案例,IMO -- 紧凑的函数,其中光标是短暂的,并且只涉及一个。
猜你喜欢
  • 2011-10-03
  • 2015-04-08
  • 1970-01-01
  • 2011-10-28
  • 2019-02-19
  • 1970-01-01
  • 2011-06-11
  • 2016-11-01
  • 2022-11-10
相关资源
最近更新 更多