如何访问包含在 sqlalchemy 错误中的 psycopg2 错误

Jon*_*ond 3 python error-handling sqlalchemy psycopg2

我正在使用 SQLalchemy 和 psycopg2 将 Pandas 数据框上传到 Postgres 中的表。如何访问 SQLalchemy 错误中的 psycopg2 错误?

我想仅在由于违反非空约束的列中的空值而引发错误时才将异常写入我的代码。我知道如何使用 psycopg2 测试这个确切的 pSQL 错误,但是当我运行我的代码时,它返回一个 SQLalchemy 错误。

这是错误:

SQLalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) 列中的空值...

这是必要的例外:

from sqlalchemy import exc

try:
    df.to_sql(name='sql_table', con=engine, if_exists='append', index=False)
except exc.IntegrityError:
Run Code Online (Sandbox Code Playgroud)

这是我想要做的:

from sqlalchemy import exc
import psycopg2

try:
    df.to_sql(name='sql_table', con=engine, if_exists='append', index=False)
except exc.IntegrityError as ex:
    ex = ex.psycopg2error
    if ex.pgcode == '23502'
        print('Data not uploaded: null value in a column violates non-null constraint')
    else:
        raise
Run Code Online (Sandbox Code Playgroud)

我知道我可以 test sqlalchemy.exc.IntegrityEror.orig,但这不像使用pgcode成员那样干净或细粒度。

Sup*_*oot 7

正如您在问题中指出的那样,您可以通过.origSQLAlchemy 异常的属性访问 dbapi 引发的底层异常。

由驱动程序引发并通过 SQLAlchemy 传播的任何异常都由 的子类包装DBAPIError,其文档状态如下:

包装的异常对象在 orig 属性中可用。它的类型和属性是特定于 DB-API 实现的

(强调我的)

查看 psycopg 文档以了解Error他们命名的基本属性之一pgcode

表示后端返回的错误代码的字符串,如果不可用则为 None。errorcodes 模块包含表示 PostgreSQL 错误代码的符号常量。

所以,<sqla_exc>.orig.pgcode看起来它应该得到你想要的,但是如果出于某种原因 psycopg 没有让他们的代码在他们的异常状态下可用,这并不是 sqlalchemy 可以解决的真正问题,因为它只是包装他们的异常并将其传递给你.


Jon*_*ond 5

这是我最终的参考代码:

try:
    df.to_sql(name='sql_table', con=engine, if_exists='append', index=False)
except exc.DBAPIError as ex:
    if ex.orig.pgcode == '23502':
        print("Data could not be uploaded to sql_table: " + ex.orig.diag.message_primary)
    else:
        raise
Run Code Online (Sandbox Code Playgroud)