PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

IntegrityError :distinction entre la contrainte unique et les violations non nulles

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.