psycopg2 fournit le SQLSTATE
à l'exception du pgcode
membre, qui vous donne des informations d'erreur assez précises sur lesquelles faire correspondre.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Voir Annexe A :Codes d'erreur dans le manuel PostgreSQL pour les significations du code. Notez que vous pouvez faire correspondre grossièrement les deux premiers caractères pour les grandes catégories. Dans ce cas, je peux voir que SQLSTATE 42601 est syntax_error
dans Syntax Error or Access Rule Violation
catégorie.
Les codes que vous voulez sont :
23505 unique_violation
23502 not_null_violation
vous pourriez donc écrire :
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
Cela dit, c'est une mauvaise façon de faire un upsert
ou merge
. @pr0gg3d a probablement raison de suggérer la bonne façon de le faire avec Django ; Je ne fais pas de Django donc je ne peux pas commenter ce morceau. Pour des informations générales sur upsert/merge, voir l'article de depesz sur le sujet.