psycopg2 fornisce SQLSTATE
con l'eccezione di pgcode
membro, che fornisce informazioni sull'errore abbastanza dettagliate su cui eseguire la corrispondenza.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Vedi Appendice A:Codici di errore nel manuale di PostgreSQL per i significati del codice. Nota che puoi abbinare grossolanamente i primi due caratteri per categorie ampie. In questo caso posso vedere che SQLSTATE 42601 è syntax_error
in Syntax Error or Access Rule Violation
categoria.
I codici che desideri sono:
23505 unique_violation
23502 not_null_violation
quindi potresti scrivere:
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
Detto questo, questo è un brutto modo per fare un upsert
o merge
. @pr0gg3d presumibilmente ha ragione nel suggerire il modo giusto per farlo con Django; Non faccio Django, quindi non posso commentare quel bit. Per informazioni generali su upsert/merge, vedere l'articolo di depesz sull'argomento.