2 Pregunta: Cómo acceder al error psycopg2 envuelto en error sqlalchemy

pregunta creada en Wed, May 8, 2019 12:00 AM

Estoy cargando un marco de datos de pandas a una tabla en Postgres usando SQLalchemy y psycopg2. ¬ŅC√≥mo accedo al error psycopg2 que est√° dentro del error SQLalchemy?

Quiero escribir una excepción en mi código solo cuando genera un error debido a un valor nulo en una columna que viola la restricción no nula. Sé cómo probar este error pSQL exacto con psycopg2, pero cuando ejecuto mi código, devuelve un error SQLalchemy.

Aquí está el error:

  

SQLalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) valor nulo en la columna ...

Aquí está la excepción necesaria:

from sqlalchemy import exc

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

Esto es lo que quiero hacer:

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

Sé que puedo realizar la prueba sqlalchemy.exc.IntegrityEror.orig, pero no es tan limpio ni preciso como usar el miembro pgcode.

    
0
2 Respuestas                              2                         

Como ha se√Īalado en su pregunta, puede acceder a la excepci√≥n subyacente generada por el dbapi a trav√©s del atributo .orig de la excepci√≥n SQLAlchemy.

Cualquier excepción generada por el controlador y propagada a través de SQLAlchemy está envuelta por una subclase de DBAPIError , donde se encuentra el estado de la documentación:

  

El objeto de excepción envuelto está disponible en el atributo orig. Es   el tipo y las propiedades son específicos de la implementación de DB-API .

(énfasis mío)

Buscando en la documentación de psycopg su base 0600350991111101010310621010101031062101010103 los atributos que nombran son Error:

  

Cadena que representa el código de error devuelto por el backend, Ninguno si   no disponible. El módulo de códigos de error contiene constantes simbólicas.   representando los códigos de error de PostgreSQL.

Entonces, pgcode parece que debería obtener lo que está buscando, pero si por alguna razón, psycopg no hace que su código esté disponible en su estado de excepción, no es realmente algo que sqlalchemy pueda abordar ya que simplemente envuelve su excepción y pasa en ti.

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

Aquí está mi código final para referencia:

<sqla_exc>.orig.pgcode     
1
2019-05-10 15: 22: 15Z
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
fuente colocada aquí