psycopg2 cung cấp SQLSTATE
với ngoại lệ là pgcode
thành viên, cung cấp cho bạn thông tin lỗi khá chi tiết để đối sánh.
python3
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=regress")
>>> curs = conn.cursor()
>>> try:
... curs.execute("INVALID;")
... except Exception as ex:
... xx = ex
>>> xx.pgcode
'42601'
Xem Phụ lục A:Mã lỗi trong sổ tay PostgreSQL để biết ý nghĩa mã. Lưu ý rằng bạn có thể so khớp thô trên hai ký tự đầu tiên cho các danh mục rộng. Trong trường hợp này, tôi có thể thấy rằng SQLSTATE 42601 là syntax_error
trong Syntax Error or Access Rule Violation
danh mục.
Các mã bạn muốn là:
23505 unique_violation
23502 not_null_violation
vì vậy bạn có thể viết:
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
Điều đó nói rằng, đây là một cách không tốt để thực hiện upsert
hoặc merge
. @ pr0gg3d có lẽ đúng khi đề xuất cách thực hiện đúng với Django; Tôi không làm Django nên tôi không thể bình luận về điều đó. Để biết thông tin chung về nâng cấp / hợp nhất, hãy xem bài viết của depesz về chủ đề này.