2 Pytanie: Jak uzyskać dostęp do błędu psycopg2 zawiniętego w błędzie sqlalchemy

pytanie utworzone w Wed, May 8, 2019 12:00 AM

Przesyłam ramkę danych pand do tabeli w Postgres przy użyciu SQLalchemy i psycopg2. Jak uzyskać dostęp do błędu psycopg2, który mieści się w błędzie SQLalchemy?

Chcę napisać wyjątek do mojego kodu tylko wtedy, gdy wywołuje błąd z powodu wartości pustej w kolumnie, która narusza ograniczenie niezerowe. Wiem, jak przetestować ten dokładny błąd pSQL za pomocą psycopg2, ale gdy uruchomię mój kod, zwraca błąd SQLalchemy.

Oto błąd:

  

SQLalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) wartość null w kolumnie ...

Oto niezbędny wyjątek:

from sqlalchemy import exc

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

Oto, co chcę zrobić:

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

Wiem, że mogę przetestować sqlalchemy.exc.IntegrityEror.orig, ale to nie jest tak czyste lub szczegółowe, jak użycie członka pgcode.

    
0
2 odpowiedzi                              2                         

Jak już zauważyłeś w swoim pytaniu, możesz uzyskać dostęp do podstawowego wyjątku zgłoszonego przez dbapi za pomocą atrybutu .orig wyjątku SQLAlchemy.

Każdy wyjątek podniesiony przez sterownik i propagowany przez SQLAlchemy jest zawijany przez podklasę DBAPIError , gdzie jest stan dokumentów:

  

Zawinięty obiekt wyjątku jest dostępny w atrybucie orig. To   typ i właściwości są specyficzne dla implementacji API DB .

(podkreślenie moje)

Przeglądanie dokumentów psycopg dla ich bazy Error jeden z atrybuty, które nazywają się pgcode:

  

Ciąg reprezentujący kod błędu zwrócony przez backend, None if   niedostępne. Moduł kodów błędów zawiera stałe symboliczne   reprezentowanie kodów błędów PostgreSQL.

Tak więc <sqla_exc>.orig.pgcode wygląda na to, że powinien dostać to, czego szukasz, ale jeśli z jakiegoś powodu psycopg nie udostępni swojego kodu w stanie wyjątku, nie jest to coś, co sqlalchemy może zaadresować, ponieważ po prostu zawija wyjątek i przechodzi to do ciebie.

    
2
2019-05-09 00: 47: 07Z

Oto mój ostateczny kod do odwołania:

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
    
1
2019-05-10 15: 22: 15Z
źródło umieszczone tutaj