psycopg2 предоставя SQLSTATE
с изключение като pgcode
член, което ви дава доста подробна информация за грешки, за да съпоставите.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Вижте Приложение A:Кодове за грешки в ръководството на PostgreSQL за значенията на кода. Имайте предвид, че можете да съпоставите грубо на първите два знака за широки категории. В този случай мога да видя, че SQLSTATE 42601 е syntax_error
в Syntax Error or Access Rule Violation
категория.
Кодовете, които искате, са:
23505 unique_violation
23502 not_null_violation
така че можете да напишете:
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
Въпреки това, това е лош начин да направите upsert
или merge
. @pr0gg3d вероятно е прав, като предлага правилния начин да го направите с Django; Аз не правя Django, така че не мога да коментирам това малко. За обща информация относно upsert/merge вижте статията на depesz по темата.