使用 Psycopg2 在 Postgres 中回滚事务后打开的游标会发生什么情况?

What happens to an open cursor after rolling back the transaction in Postgres using Psycopg2?

我正在尝试使用 Psycopg2 的CSV 文件列表复制到 Postgres copy_expert().

我正在打开游标对每个文件分别执行复制命令,并在复制数据后关闭它。 但是,如果我在此过程中遇到任何文件错误,我将回滚事务。

如果出现错误,我不确定在复制 CSV 文件之前打开的光标会发生什么情况。

连接完成回滚后它会自动关闭还是会保持原样?

我已经检查了 psycopg2 http://initd.org/psycopg/docs/connection.html#connection.rollback 上的回滚文档。但是,我仍然不确定未关闭的游标会发生什么,因为他们没有在文档中提到与游标相关的任何内容。

try:
    for tablename, filename in self.mapping:
        cur = self.conn.cursor()
        filename = f"{self.to_db}{wid}-{filename}"
        filename = f"{os.path.join(self.directory, filename)}.csv"
        sql = f"copy {tablename} from stdin with delimiter as ',' csv header;"
        with open(f"{filename}", 'r') as file:
            cur.copy_expert(sql, file)
        cur.close()
    self.conn.commit()
except Exception as e:
    self.conn.rollback()
    return e

您可以使用游标的上下文管理器,当代码离开“with”块时,游标会自动关闭。
由于您是在 for 循环之后触发提交,因此无需 're-create' 每次循环迭代都游标。

class foo():
    def __init__(self):
        self.conn = psycopg2.connect('host=...')

    def whatever(self):
        with self.conn.cursor() as cur:
            try:
                for tablename, filename in self.mapping:
                    filename = f"{self.to_db}{wid}-{filename}"
                    filename = f"{os.path.join(self.directory, filename)}.csv"
                    sql = f"copy {tablename} from stdin with delimiter as ',' csv header;"
                    with open(f"{filename}", 'r') as file:
                        cur.copy_expert(sql, file)
                self.conn.commit()
            except Exception as e:
                self.conn.rollback()
                return e