{"record":{"id":"9941a717c2211010","repo":"pola-rs/polars","slug":"unable-to-identify-string-connection-as-valid-odbc","errorCode":null,"errorMessage":"unable to identify string connection as valid ODBC (no driver)","messagePattern":"unable to identify string connection as valid ODBC \\(no driver\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/database/functions.py","lineNumber":259,"sourceCode":"    ... )  # doctest: +SKIP\n\n    \"\"\"  # noqa: W505\n    if isinstance(connection, str):\n        # check for odbc connection string\n        if re.search(r\"\\bdriver\\s*=\\s*{[^}]+?}\", connection, re.IGNORECASE):\n            _ = import_optional(\n                module_name=\"arrow_odbc\",\n                err_prefix=\"use of ODBC connection string requires the\",\n                err_suffix=\"package\",\n            )\n            connection = ODBCCursorProxy(connection)\n        elif \"://\" in connection:\n            # otherwise looks like a mistaken call to read_database_uri\n            msg = \"string URI is invalid here; call `read_database_uri` instead\"\n            raise ValueError(msg)\n        else:\n            msg = \"unable to identify string connection as valid ODBC (no driver)\"\n            raise ValueError(msg)\n\n    # adbc_driver_manager must be >= 1.7.0 to support passing Python sequences into\n    # parameterised queries (via execute_options) without PyArrow installed\n    if (\n        execute_options is not None\n        and not _PYARROW_AVAILABLE\n        and type(connection).__module__.split(\".\", 1)[0].startswith(\"adbc\")\n    ):\n        adbc_version_no_pyarrow_required = \"1.7.0\"\n        adbc_driver_manager = import_optional(\"adbc_driver_manager\")\n        adbc_str_version = getattr(adbc_driver_manager, \"__version__\", \"0.0\")\n        if not parse_version(adbc_str_version) >= parse_version(\n            adbc_version_no_pyarrow_required\n        ):\n            msg = (\n                \"pyarrow is required for adbc-driver-manager < \"\n                f\"{adbc_version_no_pyarrow_required} when using parameterized queries (via \"\n                f\"`execute_options`), found {adbc_str_version}.\\nEither upgrade \"","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/database/functions.py#L241-L277","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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()"],"exampleFix":"# before\npl.read_database(q, \"MyDsn\")\n\n# after\nimport pyodbc\npl.read_database(q, pyodbc.connect(\"DSN=MyDsn;UID=u;PWD=p\"))","handlingStrategy":"validation","validationCode":"import re\n\ndef as_connection(s: str):\n    if re.search(r\"\\bdriver\\s*=\\s*{[^}]+?}\", s, re.IGNORECASE) or \"://\" in s:\n        return s  # handled downstream (ODBC proxy / read_database_uri)\n    import pyodbc\n    return pyodbc.connect(f\"DSN={s}\")  # treat bare string as DSN","typeGuard":"def looks_like_odbc_string(s: str) -> bool:\n    import re\n    return re.search(r\"\\bdriver\\s*=\\s*{[^}]+?}\", s, re.IGNORECASE) is not None","tryCatchPattern":null,"preventionTips":["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"],"tags":["database","odbc","connection-string","api-misuse"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}