psycopg2 fornece o
SQLSTATE
com exceção do pgcode
member, que fornece informações de erro bastante refinadas para correspondência. 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 o Apêndice A:Códigos de erro no manual do PostgreSQL para significados de código. Observe que você pode corresponder grosseiramente nos dois primeiros caracteres para categorias amplas. Neste caso, posso ver que SQLSTATE 42601 é
syntax_error
no Syntax Error or Access Rule Violation
categoria. Os códigos que você deseja são:
23505 unique_violation
23502 not_null_violation
então você poderia escrever:
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
Dito isto, esta é uma maneira ruim de fazer um
upsert
ou merge
. @pr0gg3d provavelmente está certo em sugerir a maneira certa de fazer isso com o Django; Eu não faço Django, então não posso comentar sobre isso. Para informações gerais sobre upsert/merge veja o artigo do depesz sobre o tópico.