psycopg2 tillhandahåller SQLSTATE
med undantaget som pgcode
medlem, vilket ger dig ganska finkornig felinformation att matcha på.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Se Bilaga A:Felkoder i PostgreSQL-manualen för kodbetydelser. Observera att du kan matcha grovt på de två första tecknen för breda kategorier. I det här fallet kan jag se att SQLSTATE 42601 är syntax_error
i Syntax Error or Access Rule Violation
kategori.
Koderna du vill ha är:
23505 unique_violation
23502 not_null_violation
så du kan skriva:
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
Som sagt, det här är ett dåligt sätt att göra en upsert
eller merge
. @pr0gg3d har förmodligen rätt i att föreslå det rätta sättet att göra det med Django; Jag gör inte Django så jag kan inte kommentera den biten. För allmän information om upsert/merge se depesz artikel om ämnet.