Как получить доступ к ошибке psycopg2, завернутой в ошибку sqlalchemy - PullRequest
0 голосов
/ 08 мая 2019

Я загружаю фрейм данных панд в таблицу в Postgres, используя SQLalchemy и psycopg2.Как получить доступ к ошибке psycopg2, содержащейся в ошибке SQLalchemy?

Я хочу записать исключение в мой код только в том случае, если возникает ошибка из-за нулевого значения в столбце, которое нарушает ненулевое ограничение.Я знаю, как проверить эту точную ошибку pSQL с помощью psycopg2, но когда я запускаю свой код, он возвращает ошибку 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:

Вот что я хочу сделать:

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

Я знаю, что могу проверить sqlalchemy.exc.IntegrityEror.orig, но это не так чисто или мелкозернисто, как при использовании элемента pgcode.

Ответы [ 2 ]

2 голосов
/ 09 мая 2019

Как вы указали в своем вопросе, вы можете получить доступ к базовому исключению, вызванному dbapi, через атрибут .orig исключения SQLAlchemy.

Любое исключение, которое вызывается драйвером и распространяется через SQLAlchemy, заключено в подкласс DBAPIError, где находится состояние документа:

Обернутый объект исключения доступен в атрибуте orig. Сво тип и свойства зависят от реализации DB-API .

(акцент мой)

Глядя на документацию psycopg для их базы Error один из атрибутов, которые они называют pgcode:

Строка, представляющая код ошибки, возвращенный бэкэндом, Нет, если недоступен. Модуль кодов ошибок содержит символические константы представляет коды ошибок PostgreSQL.

Итак, <sqla_exc>.orig.pgcode выглядит так, как будто оно должно получить то, что вы ищете, но если по какой-то причине psycopg не делает свой код доступным в своем состоянии исключения, это на самом деле не то, что sqlalchemy может решить, так как он просто оборачивает их исключение и передает это вам.

1 голос
/ 10 мая 2019

Вот мой окончательный код для справки:

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
...