pola-rs/polars · error · ValueError
unable to identify string connection as valid ODBC (no drive
Error message
unable to identify string connection as valid ODBC (no driver)
What it means
Raised by read_database() when the connection argument is a string that is neither an ODBC connection string (matching 'driver={...}' case-insensitively) nor a URI (no '://'). Polars cannot tell what kind of connection a bare string is meant to be, so it refuses it.
Source
Thrown at py-polars/src/polars/io/database/functions.py:259
... ) # doctest: +SKIP
""" # noqa: W505
if isinstance(connection, str):
# check for odbc connection string
if re.search(r"\bdriver\s*=\s*{[^}]+?}", connection, re.IGNORECASE):
_ = import_optional(
module_name="arrow_odbc",
err_prefix="use of ODBC connection string requires the",
err_suffix="package",
)
connection = ODBCCursorProxy(connection)
elif "://" in connection:
# otherwise looks like a mistaken call to read_database_uri
msg = "string URI is invalid here; call `read_database_uri` instead"
raise ValueError(msg)
else:
msg = "unable to identify string connection as valid ODBC (no driver)"
raise ValueError(msg)
# adbc_driver_manager must be >= 1.7.0 to support passing Python sequences into
# parameterised queries (via execute_options) without PyArrow installed
if (
execute_options is not None
and not _PYARROW_AVAILABLE
and type(connection).__module__.split(".", 1)[0].startswith("adbc")
):
adbc_version_no_pyarrow_required = "1.7.0"
adbc_driver_manager = import_optional("adbc_driver_manager")
adbc_str_version = getattr(adbc_driver_manager, "__version__", "0.0")
if not parse_version(adbc_str_version) >= parse_version(
adbc_version_no_pyarrow_required
):
msg = (
"pyarrow is required for adbc-driver-manager < "
f"{adbc_version_no_pyarrow_required} when using parameterized queries (via "
f"`execute_options`), found {adbc_str_version}.\nEither upgrade "View on GitHub (pinned to df599052da)
Solutions
- Pass an actual connection object instead: pyodbc.connect('DSN=MyDsn;...') or sqlalchemy.create_engine(...).connect()
- If ODBC string input is intended, use the full form with a driver block, e.g. 'Driver={PostgreSQL Unicode};Server=...;' — and have arrow_odbc installed, as that path requires it
- For URI-style access, switch to pl.read_database_uri()
Example fix
# before
pl.read_database(q, "MyDsn")
# after
import pyodbc
pl.read_database(q, pyodbc.connect("DSN=MyDsn;UID=u;PWD=p")) Defensive patterns
Strategy: validation
Validate before calling
import re
def as_connection(s: str):
if re.search(r"\bdriver\s*=\s*{[^}]+?}", s, re.IGNORECASE) or "://" in s:
return s # handled downstream (ODBC proxy / read_database_uri)
import pyodbc
return pyodbc.connect(f"DSN={s}") # treat bare string as DSN Type guard
def looks_like_odbc_string(s: str) -> bool:
import re
return re.search(r"\bdriver\s*=\s*{[^}]+?}", s, re.IGNORECASE) is not None Prevention
- Resolve DSNs yourself with pyodbc.connect('DSN=...') before calling read_database
- Keep the full 'Driver={...};...' form for ODBC string input and install arrow_odbc
- Prefer URI access via read_database_uri where the backend allows it
When it happens
Trigger: Passing a bare ODBC DSN name (e.g. 'MyDsn') or a malformed/partial connection string to read_database(); an ODBC string whose driver clause uses parentheses or different casing/format that fails the 'driver={...}' regex.
Common situations: Windows ODBC workflows where code elsewhere used just the DSN; hand-typed connection strings with a typo in the Driver={...} block; expecting DSN resolution that read_database does not perform.
Related errors
- Unrecognised connection type {qualified_type_name(conn)!r};
- cannot return a frame before executing a query
- string URI is invalid here; call `read_database_uri` instead
- expected connection to be a URI string; found {qualified_typ
- Event loop stopped before Future completed.
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/9941a717c2211010.
Report an issue: GitHub.