psycopg2 zapewnia SQLSTATE
z wyjątkiem jako pgcode
członka, który daje dość szczegółowe informacje o błędach, które można dopasować.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Zobacz Dodatek A:Kody błędów w podręczniku PostgreSQL dla znaczeń kodu. Pamiętaj, że możesz dopasować zgrubnie na pierwszych dwóch znakach dla ogólnych kategorii. W tym przypadku widzę, że SQLSTATE 42601 to syntax_error
w Syntax Error or Access Rule Violation
kategorii.
Potrzebne kody to:
23505 unique_violation
23502 not_null_violation
więc możesz napisać:
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
To powiedziawszy, to zły sposób na wykonanie upsert
lub merge
. @pr0gg3d prawdopodobnie ma rację, sugerując właściwy sposób na zrobienie tego z Django; Nie używam Django, więc nie mogę tego komentować. Aby uzyskać ogólne informacje na temat upsert/merge, zobacz artykuł depesz na ten temat.