psycopg2 proporciona el SQLSTATE
con la excepción de pgcode
miembro, que le brinda información de error bastante detallada para hacer coincidir.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Consulte el Apéndice A:Códigos de error en el manual de PostgreSQL para conocer los significados del código. Tenga en cuenta que puede hacer coincidir aproximadamente los dos primeros caracteres para categorías amplias. En este caso puedo ver que SQLSTATE 42601 es syntax_error
en el Syntax Error or Access Rule Violation
categoría.
Los códigos que quieres son:
23505 unique_violation
23502 not_null_violation
así que podrías escribir:
try:
principal = cls.objects.create(
user_id=user.id,
email=user.email,
path='something'
)
except IntegrityError as ex:
if ex.pgcode == '23505':
principal = cls.objects.get(
user_id=user.id,
email=user.email
)
else:
raise
Dicho esto, esta es una mala manera de hacer un upsert
o merge
. @pr0gg3d presumiblemente tiene razón al sugerir la forma correcta de hacerlo con Django; No hago Django, así que no puedo comentar sobre eso. Para obtener información general sobre upsert/merge, consulte el artículo de depesz sobre el tema.