PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

IntegrityError:Unterscheidung zwischen Unique Constraint und Not-Null-Verletzungen

psycopg2 liefert den SQLSTATE mit Ausnahme des pgcode Mitglied, das Ihnen ziemlich detaillierte Fehlerinformationen zum Abgleichen gibt.

python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
...     curs.execute("INVALID;")
... except Exception as ex:
...     xx = ex
>>> xx.pgcode
'42601'

Siehe Anhang A:Fehlercodes im PostgreSQL-Handbuch für Codebedeutungen. Beachten Sie, dass Sie die ersten beiden Zeichen für breite Kategorien grob abgleichen können. In diesem Fall kann ich sehen, dass SQLSTATE 42601 syntax_error ist im Syntax Error or Access Rule Violation Kategorie.

Die gewünschten Codes sind:

23505   unique_violation
23502   not_null_violation

so könnte man schreiben:

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

Allerdings ist dies ein schlechter Weg, um einen upsert durchzuführen oder merge . @pr0gg3d hat vermutlich Recht, wenn er den richtigen Weg vorschlägt, es mit Django zu tun; Ich mache kein Django, also kann ich dazu nichts sagen. Allgemeine Informationen zu Upsert/Merge finden Sie in depesz's Artikel zu diesem Thema.