默认的psycopg2错误消息太宽泛。大部分时间它只是抛出:
psycopg2.OperationalError
没有任何其他信息。因此很难猜测,错误的真正原因是什么 - 不正确的用户凭据,或者仅仅是服务器未运行的事实。所以,我需要一些更合适的错误处理,比如pymysql
库中的错误代码。
我看过this页面,但它没有帮助。当我做的时候
except Exception as err:
print(err.pgcode)
它始终打印无。至于errorcodes
,它只是未定义的。我试图导入它,但失败了。所以,我需要一些帮助。
答案 0 :(得分:0)
对于任何想要快速回答的人:
import traceback # Just to show the full traceback
from psycopg2 import errors
InFailedSqlTransaction = errors.lookup('25P02')
try:
feed = self._create_feed(data)
except InFailedSqlTransaction:
traceback.print_exc()
self._cr.rollback()
pass # Continue / throw ...
psycopg2 -> erros.py
,您将找到查找功能lookup(code)
。psycopg2\_psycopg\__init__.py
中的 sqlstate_errors
,您会找到所有要作为字符串添加到 lookup
函数中的代码。答案 1 :(得分:0)
这不是问题的答案,而只是我的想法,不适合发表评论。 在这种情况下,我认为在异常对象中设置 pgcode
会有所帮助,但不幸的是,情况并非如此。
我正在实现一个类似 pg_isready
的 Python 脚本来测试 Postgres 服务是否在给定的地址和端口(例如,localhost
和 49136
)上运行。地址和端口可能会或可能不会被任何其他程序使用。
pg_isready
在内部调用 internal_ping()
。注意Here begins the interesting part of "ping": determine the cause...
的评论:
/*
* Here begins the interesting part of "ping": determine the cause of the
* failure in sufficient detail to decide what to return. We do not want
* to report that the server is not up just because we didn't have a valid
* password, for example. In fact, any sort of authentication request
* implies the server is up. (We need this check since the libpq side of
* things might have pulled the plug on the connection before getting an
* error as such from the postmaster.)
*/
if (conn->auth_req_received)
return PQPING_OK;
所以 pg_isready
还使用了这样一个事实,即连接上的无效身份验证错误意味着连接本身已经成功,因此服务也已启动。因此,我可以按如下方式实现:
ready = True
try:
psycopg2.connect(
host=address,
port=port,
password=password,
connect_timeout=timeout,
)
except psycopg2.OperationalError as ex:
ready = ("fe_sendauth: no password supplied" in except_msg)
然而,当异常 psycopg2.OperationalError
被捕获时,ex.pgcode
为 None
。因此,我无法使用错误代码进行比较并查看异常是否与身份验证/授权有关。我必须检查异常是否有特定消息(如@dhke 指出的in the comment),我认为这有点脆弱,因为错误消息可能会在未来版本中更改,但错误代码很多我认为不太可能改变。