处理 psycopg2 中的错误 - 一个错误似乎会产生更多错误?

Handling errors in psycopg2 - one error seems to create more?

我正在使用 Python 2 和 psycopg2 v2.6.2。我正在 运行 执行一系列 psycopg2 命令,并捕获任何错误:

for r in records:
  county = r[0]
  q = 'INSERT INTO allparcels(county, geom) '
  q += "SELECT %s, ST_Union(ST_Buffer(wkb_geometry, 0)) FROM parcel "
  q += "WHERE county=%s"
  print q % (county, county)
  try:
    cursor.execute(q, (county, county))
    conn.commit()
  except Exception, e:
    print e
    print e.pgerror
cursor.close()
conn.close()

这是前几行记录的 运行s,然后我快速连续地得到所有其余行的 ERROR: current transaction is aborted, commands ignored until end of transaction block

奇怪的是,如果我使用后面的命令之一 运行 直接在我的数据库中,它工作正常。所以我认为后面的错误与 psycopg2 和我的错误处理有关,而不是 SQL 命令。

我想我一定没有正确处理错误。我希望我的脚本打印错误,然后顺利地继续下一个命令。

我应该怎么做呢?

这里的问题如下:

try:
    # it is this specific line that causes an error
    cursor.execute(q, (county, county))

    # this never happens, so the transaction is still open
    conn.commit()
except Exception, e:
    ...
    # you never issued a rollback on the transaction ... its still open

如您所见,如果 cursor.execute 失败,那么您既不会尝试提交事务也不会将其回滚。循环中的下一次迭代将尝试对已中止但未回滚的事务执行 SQL。

相反,您需要遵循这种模式

try:
    cursor.execute(...)
except Exception, e:
    conn.rollback()
else:
    conn.commit()

donkopotamus 的回答很不错。它有一个问题,因为它会回滚整个事务,如果您将此查询作为更大事务块的一部分执行,这绝对是不受欢迎的行为。如果此查询是较大事务块的一部分,请考虑使用保存点:

try:
    cursor.execute("savepoint my_save_point")
    cursor.execute(query)
except:
    cursor.execute("rollback to savepoint my_save_point")
finally:
    cursor.execute("release savepoint my_save_point")

psycopg2.errors.InFailedSqlTransaction: 当前事务被中止,命令被忽略直到事务块结束

当我要在数据库中插入一些数据时出现此错误。

这已通过 增加 TABLE 中的属性 的大小解决。