处理 Postgres 服务器端错误的正确方法是什么

What is the proper way to handle Postgres server side errors

我正在使用 psycopg2 从我的 Postgres 服务器查询,这是查询的代码:

def execute_query(
        self,
        query,
        query_params=None,
        cursor_factory=psycopg2.extras.NamedTupleCursor,
    ):
        try:
            self.connect()
            cursor_id = uuid.uuid4().hex

            with self.connection.cursor(
                cursor_id,
                cursor_factory=cursor_factory,
            ) as cursor:
                cursor.execute(
                    query,
                    query_params,
                )

                yield from cursor
        finally:
            self.disconnect()

有时没有任何服务器指示(正常 CPU & RAM 使用),连接中断。 当它这样做时,它会引发以下异常之一:

psycopg2.OperationalError: connection pointer is NULL
psycopg2.InterfaceError: cursor already closed

我不确定处理这些特定异常的正确方法是否是重试:

    def execute_query(
        self,
        query,
        page_size=2000,
        query_params=None,
        cursor_factory=psycopg2.extras.NamedTupleCursor,
    ):
        try:
            self.connect()
            cursor_id = uuid.uuid4().hex

            with self.connection.cursor(
                cursor_id,
                cursor_factory=cursor_factory,
            ) as cursor:
                cursor.itersize = page_size
                cursor.execute(
                    query,
                    query_params,
                )

                yield from cursor
        except (
            psycopg2.OperationalError,
            psycopg2.InterfaceError,
        ):
            self.execute_query(
                query=query,
                page_size=page_size,
                query_params=query_params,
                cursor_factory=cursor_factory,
            )
        finally:
            self.disconnect()

我想知道是否有任何方法可以预测这些异常而不在它已经引发后捕获它

谢谢!

根据我的经验,在某种类型的两台服务器之间进行通信时没有魔术。而且您无法预测它们何时会发生 ose 异常。所以我会建议首先在一切都中断时管理响应。与深入研究 psycopg2 代码相比,这是更多的心态和一般设计建议。 我将添加一些我使用的快速提示,希望这对您有所帮助 :D

跟踪您的例外情况

在使用服务器-客户端应用程序时会出现奇怪的结果,请记住,有大量错误是您无法os合理控制and/or预测的,但这并不意味着您无法分类他们并相应地升级您的代码。一件好事是将您的异常分开并逐一处理。

存在未处理的异常行为

它可以每 x 秒重试一次,可以将其提升以使其可见,或者重试并将回溯和异常名称存储在日志中以便稍后对其进行分类。

监控您的服务器,但不要太担心它

既然是内部使用,为了学习尽量找出每个错误背后的原因是有好处的。但是有很多不太明显的因素会干扰您的查询,例如:局域网电缆损坏,os 服务器崩溃并快速恢复,wifi 连接中的噪音,并发性,数据库大小等。 因此,让您的默认错误行为到位,并努力让您的方法在第一次尝试时表现不完美。

交易是你最好的朋友

我将开始假设您的查询属于以下两类之一:

  • DQL(Data Query Language):问事(SELECT)。这些都是简单的
  • DML(数据操作语言):编辑数据(删除、更新、插入……)

(有关查询类型的更多信息,我留给您 link:https://www.geeksforgeeks.org/sql-ddl-dql-dml-dcl-tcl-commands/

DML 查询应该始终在事务中被封装os,以避免出现意外错误时出现不一致:Transactions in PostgreSQL

如果您正在修改数据并且某些东西在中途崩溃,事务可以通过撤消未完成的内容来帮助您。

希望对您有所帮助,祝您编码愉快!!