Skip to content

no-unique-violation-message-match

Do not make unique-violation control flow depend on rendered exception text.

Why

Database error text is localized and can change with driver or server versions; supported PostgreSQL drivers expose the violated constraint as structured diagnostic data.

Fix

Compare the driver's structured constraint field: exc.diag.constraint_name for psycopg or exc.constraint_name for asyncpg. SQLSTATE 23505 identifies the violation category, not the constraint.

Examples

Before — flagged Unique constraint selected from error text
app/store.py
from psycopg import errors
try:
save()
except errors.UniqueViolation as exc:
if "user_email_key" in str(exc):
raise DuplicateEmail from exc
raise
After — preferred Unique constraint selected from structured diagnostics
app/store.py
from psycopg import errors
try:
save()
except errors.UniqueViolation as exc:
if exc.diag.constraint_name == "user_email_key":
raise DuplicateEmail from exc
raise