zylon-ai/private-gpt · error · ValueError
MySQL connection requires mysql, mysql+mysqldb, or mysql+pym
Error message
MySQL connection requires mysql, mysql+mysqldb, or mysql+pymysql scheme
What it means
Raised while preparing a MySQL connection string: the component normalizes mysql and mysql+mysqldb schemes to mysql+pymysql (because pymysql is the supported driver), and rejects any other scheme such as mysql+asyncpg, mysql+mysqlconnector, or a bare typo. This guarantees the SQLAlchemy engine is always built on pymysql, which the rest of the tabular query path expects.
Source
Thrown at private_gpt/components/tabular/database_query_generator.py:445
if self._dialect in [Dialects.TSQL]:
# MSSQL specific adjustments
if not any(k.lower() == "encrypt" for k in params):
params["Encrypt"] = ["yes" if self.ssl else "no"]
if not any(k.lower() == "driver" for k in params):
if not parsed.scheme.startswith("mssql+pyodbc"):
raise ValueError(
"MSSQL connection requires pyodbc scheme when no driver specified"
)
params["driver"] = ["ODBC Driver 18 for SQL Server"]
elif self._dialect in [Dialects.MYSQL]:
# MySQL specific adjustments
if parsed.scheme == "mysql" or parsed.scheme == "mysql+mysqldb":
parsed = parsed._replace(scheme="mysql+pymysql")
elif not parsed.scheme.startswith("mysql+pymysql"):
raise ValueError(
"MySQL connection requires mysql, mysql+mysqldb, or mysql+pymysql scheme"
)
if not any(k.lower() == "charset" for k in params):
params["charset"] = ["utf8mb4"]
flattened = {k: v[0] if len(v) == 1 else v for k, v in params.items()}
new_parsed = parsed._replace(query=urlencode(flattened, doseq=True))
self.connection_string = str(urlunparse(new_parsed))
def _check_connection(self) -> str | None:
"""Check if the database connection can be established.
Returns None if successful, or an error message if failed.
"""
try:
conn = self._ensure_connected()
dialect = classify_dialect(
self._engine.dialect.name if self._engine else NoneView on GitHub (pinned to 4a030776a3)
Solutions
- Use mssql-normalized MySQL form: mysql+pymysql://user:pass@host:3306/db
- Plain mysql:// or mysql+mysqldb:// also work (auto-rewritten to pymysql)
- Lowercase the scheme and double-check for typos like mysql+pymsql
Example fix
# before connection_string = "mysql+mysqlconnector://root:pass@db:3306/sakila" # after connection_string = "mysql+pymysql://root:pass@db:3306/sakila"
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
scheme = urlparse(connection_string).scheme.lower()
if scheme not in {"mysql", "mysql+mysqldb", "mysql+pymysql"}:
raise ValueError(
"MySQL URL scheme must be mysql, mysql+mysqldb, or mysql+pymysql"
) Type guard
def is_valid_mysql_url(conn: str) -> bool:
scheme = urlparse(conn).scheme.lower()
return scheme in {"mysql", "mysql+mysqldb", "mysql+pymysql"} Prevention
- Use mysql+pymysql:// as the canonical scheme (component rewrites to it anyway)
- Lowercase schemes and watch for mariadb:// or mysql+asyncpg URLs from other tooling
When it happens
Trigger: Supplying a connection string whose scheme is not mysql, mysql+mysqldb, or mysql+pymysql while the dialect resolves to MySQL — e.g. mysql+mysqlconnector://... or mariadb://...
Common situations: Reusing a URL written for a different MySQL driver stack; attempting MariaDB URLs; uppercase scheme (MySQL://) which urlparse does not lowercase, failing the exact-match checks.
Related errors
- MSSQL connection requires pyodbc scheme when no driver speci
- Invalid system item in list: {item}
- Unknown condense strategy: {strategy}
- Audio blocks found but no audio-capable LLM provided.
- Code execution provider '{name}' is not registered. Availabl
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/9d3bd33b1e012316.
Report an issue: GitHub.