在 SELECT 语句中遇到错误后需要提交(或回滚)

need to commit (or rollback) after encountering an error in SELECT statements

当在 SELECT 语句中遇到错误时,显然 TRANSACTION 保持打开状态。

与psycopg建立联系:

# ...
connection.autocommit = False
cur = connection.cursor(cursor_factory=DictCursor)

select不存在table:

cur.execute('SELECT * FROM "non_exists_table"') # a incorrect query
psycopg2.errors.UndefinedTable: relation "non_exists_table" does not exist

然后执行另一个查询:

cur.execute('SELECT * FROM "exists_table"') # this is a correct query
psycopg2.errors.InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block

为什么?

psycopg2 是否为所有 execute() 打开一个 TRANSACTION?甚至 SELECT?!!

是否可以避免在 select 查询中开始 TRANSACTION

来自 @snakecharmerb 的坦克评论

this参考:

By default, the first time a command is sent to the database (using one of the cursors created by the connection), a new transaction is created.

Should any command fail, the transaction will be aborted and no further command will be executed until a call to the rollback() method.

解决方案1:

connection.autocommit = True

解决方案2:

with psycopg2.connect(DSN) as conn:
    with conn.cursor() as curs:
        curs.execute(SQL)

如果块没有引发异常,则提交事务。如果出现异常,事务将回滚。

与文件对象或其他资源不同,退出连接的 with 块不会关闭连接,只会关闭与其关联的事务。