You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mysqlclient raises OperationalError instead of IntegrityError for all Constraint Violations #535
mysqlclient is raising OperationalError instead of IntegrityError for all constraint violations, such as not null, unique, foreign key, and check.
This is a bug because it violates the Python DB API PEP 0249. In addition, all other python drivers like mysql-connector-python, PyMySQL, cx_Oracle, psycopg2, and etc. will correctly raise IntegrityError in these cases. It seems like only mysqlclient raises OperationalError.
The Python DB API pep is clear that an IntegrityError should be raised in this case, not OperationalError. Please see the PEP here:
The PEP states that OperationalError is used for totally different errors not under the control of the programmer, such as running out of memory. Please read the description for OperationalError here: https://peps.python.org/pep-0249/#operationalerror
To Reproduce
import MySQLdb
db = MySQLdb.connect(user='mysql', passwd='mysql', db='mysql')
cur = db.cursor()
cur.execute('drop table foo')
cur.execute('create table foo (c1 int primary key)')
# This raises an OperationalError. It should raise an IntegrityError instead.
cur.execute('insert into foo values (null)')
cur.execute('insert into foo values (1)')
# This raises an OperationalError. It should raise an IntegrityError instead.
cur.execute('insert into foo values (1)')
Environment
MySQL Server
Server OS (e.g. Windows 10, Ubuntu 20.04): Windows 10
If one wants to do retries for OperationalErrors for resilience, they must look for application/integrity errors inside OperationalError manually (like forementioned constraint violations which are not retryable)
cur.execute('insert into foo values (1)')
# This raises an OperationalError. It should raise an IntegrityError instead.
cur.execute('insert into foo values (1)')
Activity
sustefil commentedon Dec 12, 2022
+1
If one wants to do retries for OperationalErrors for resilience, they must look for application/integrity errors inside OperationalError manually (like forementioned constraint violations which are not retryable)
methane commentedon Mar 13, 2023
I see IntegrityError for this query.
See test code:
https://github.com/PyMySQL/mysqlclient/pull/579/files#diff-6e5030d96839d3fe377cf209b6cab5b0d50ae900b458248d8c24b61774117170R44-R56
And its result:
https://github.com/PyMySQL/mysqlclient/actions/runs/4402624365/jobs/7709988526
Add tests for #535
ER_BAD_NULL should be IntegrityError. (#579)
mkmoisen commentedon Mar 20, 2023
Thanks @methane