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
from psycopg import errors
try: save()except errors.UniqueViolation as exc: if "user_email_key" in str(exc): raise DuplicateEmail from exc raisefrom psycopg import errors
try: save()except errors.UniqueViolation as exc: if exc.diag.constraint_name == "user_email_key": raise DuplicateEmail from exc raise