Skip to content

Commit 17855d8

Browse files
authored
Fix MySQL driver: migrate from mysql-connector-python to PyMySQL (#53)
- Update README, AUR files, and install_strategy.py to reference PyMySQL - Update tests to use pymysql instead of mysql.connector - Add migration detection for users with old mysql-connector-python installed - Update mypy overrides for pymysql module Co-authored-by: Peter Adams <18162810+Maxteabag@users.noreply.github.com>
1 parent 095e8e7 commit 17855d8

File tree

8 files changed

+42
-18
lines changed

8 files changed

+42
-18
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ Most of the time you can just run `sqlit` and connect. If a Python driver is mis
242242
| SQLite | *(built-in)* | *(built-in)* | *(built-in)* |
243243
| PostgreSQL / CockroachDB / Supabase | `psycopg2-binary` | `pipx inject sqlit-tui psycopg2-binary` | `python -m pip install psycopg2-binary` |
244244
| SQL Server | `mssql-python` | `pipx inject sqlit-tui mssql-python` | `python -m pip install mssql-python` |
245-
| MySQL | `mysql-connector-python` | `pipx inject sqlit-tui mysql-connector-python` | `python -m pip install mysql-connector-python` |
245+
| MySQL | `PyMySQL` | `pipx inject sqlit-tui PyMySQL` | `python -m pip install PyMySQL` |
246246
| MariaDB | `mariadb` | `pipx inject sqlit-tui mariadb` | `python -m pip install mariadb` |
247247
| Oracle | `oracledb` | `pipx inject sqlit-tui oracledb` | `python -m pip install oracledb` |
248248
| DuckDB | `duckdb` | `pipx inject sqlit-tui duckdb` | `python -m pip install duckdb` |

aur/.SRCINFO

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pkgbase = python-sqlit-tui
1616
depends = python-docker>=7.0.0
1717
optdepends = python-psycopg2: PostgreSQL, CockroachDB and Supabase support
1818
optdepends = python-pyodbc: SQL Server support
19-
optdepends = python-mysql-connector: MySQL support
19+
optdepends = python-pymysql: MySQL support
2020
optdepends = python-mariadb-connector: MariaDB support
2121
optdepends = python-oracledb: Oracle support
2222
optdepends = python-duckdb: DuckDB support

aur/PKGBUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ depends=(
1717
optdepends=(
1818
'python-psycopg2: PostgreSQL, CockroachDB and Supabase support'
1919
'python-pyodbc: SQL Server support'
20-
'python-mysql-connector: MySQL support'
20+
'python-pymysql: MySQL support'
2121
'python-mariadb-connector: MariaDB support'
2222
'python-oracledb: Oracle support'
2323
'python-duckdb: DuckDB support'

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ namespace_packages = true
155155

156156
[[tool.mypy.overrides]]
157157
module = [
158-
"mysql.connector",
158+
"pymysql",
159159
"mariadb",
160160
"oracledb",
161161
"duckdb",

sqlit/db/adapters/mysql.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@
22

33
from __future__ import annotations
44

5+
import importlib.util
56
from typing import TYPE_CHECKING, Any
67

8+
from ..exceptions import MissingDriverError
79
from ..schema import get_default_port
810
from .base import MySQLBaseAdapter, import_driver_module
911

1012
if TYPE_CHECKING:
1113
from ...config import ConnectionConfig
1214

1315

16+
def _check_old_mysql_connector() -> bool:
17+
"""Check if the old mysql-connector-python package is installed."""
18+
return importlib.util.find_spec("mysql.connector") is not None
19+
20+
1421
class MySQLAdapter(MySQLBaseAdapter):
1522
"""Adapter for MySQL using PyMySQL."""
1623

@@ -56,12 +63,29 @@ def driver_import_names(self) -> tuple[str, ...]:
5663

5764
def connect(self, config: ConnectionConfig) -> Any:
5865
"""Connect to MySQL database."""
59-
pymysql = import_driver_module(
60-
"pymysql",
61-
driver_name=self.name,
62-
extra_name=self.install_extra,
63-
package_name=self.install_package,
64-
)
66+
try:
67+
pymysql = import_driver_module(
68+
"pymysql",
69+
driver_name=self.name,
70+
extra_name=self.install_extra,
71+
package_name=self.install_package,
72+
)
73+
except MissingDriverError:
74+
# Check if user has the old mysql-connector-python installed
75+
if _check_old_mysql_connector():
76+
raise MissingDriverError(
77+
self.name,
78+
self.install_extra,
79+
self.install_package,
80+
module_name="pymysql",
81+
import_error=(
82+
"MySQL driver has changed from mysql-connector-python to PyMySQL.\n"
83+
"Please uninstall the old package and install PyMySQL:\n"
84+
" pip uninstall mysql-connector-python\n"
85+
" pip install PyMySQL"
86+
),
87+
) from None
88+
raise
6589

6690
port = int(config.port or get_default_port("mysql"))
6791
return pymysql.connect(

sqlit/install_strategy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def _get_arch_package_name(package_name: str) -> str | None:
158158
"psycopg2-binary": "python-psycopg2",
159159
"psycopg2": "python-psycopg2",
160160
"mssql-python": "python-mssql",
161-
"mysql-connector-python": "python-mysql-connector",
161+
"PyMySQL": "python-pymysql",
162162
"mariadb": "python-mariadb-connector",
163163
"oracledb": "python-oracledb",
164164
"duckdb": "python-duckdb",

tests/conftest.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -716,18 +716,18 @@ def mysql_db(mysql_server_ready: bool) -> str:
716716
pytest.skip("MySQL is not available")
717717

718718
try:
719-
import mysql.connector
719+
import pymysql
720720
except ImportError:
721-
pytest.skip("mysql-connector-python is not installed")
721+
pytest.skip("PyMySQL is not installed")
722722

723723
try:
724-
conn = mysql.connector.connect(
724+
conn = pymysql.connect(
725725
host=MYSQL_HOST,
726726
port=MYSQL_PORT,
727727
database=MYSQL_DATABASE,
728728
user=MYSQL_USER,
729729
password=MYSQL_PASSWORD,
730-
connection_timeout=10,
730+
connect_timeout=10,
731731
)
732732
cursor = conn.cursor()
733733

@@ -793,13 +793,13 @@ def mysql_db(mysql_server_ready: bool) -> str:
793793
yield MYSQL_DATABASE
794794

795795
try:
796-
conn = mysql.connector.connect(
796+
conn = pymysql.connect(
797797
host=MYSQL_HOST,
798798
port=MYSQL_PORT,
799799
database=MYSQL_DATABASE,
800800
user=MYSQL_USER,
801801
password=MYSQL_PASSWORD,
802-
connection_timeout=10,
802+
connect_timeout=10,
803803
)
804804
cursor = conn.cursor()
805805
cursor.execute("DROP TRIGGER IF EXISTS trg_test_users_audit")

tests/integration/python_packages/test_package_install_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ async def main() -> None:
171171
_assert_present("psycopg2")
172172

173173
# Failure path: forced install failure yields manual instructions
174-
_assert_missing("mysql.connector")
174+
_assert_missing("pymysql")
175175
await _run_flow(force_fail=True, db_type="mysql")
176176

177177

0 commit comments

Comments
 (0)