{"record":{"id":"51d68d0cba844cf5","repo":"pola-rs/polars","slug":"expected-connection-to-be-a-uri-string-found-qua","errorCode":null,"errorMessage":"expected connection to be a URI string; found {qualified_type_name(uri)!r}","messagePattern":"expected connection to be a URI string; found (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/database/functions.py","lineNumber":495,"sourceCode":"    ...     \"sqlite:///:memory:\",\n    ...     engine=\"adbc\",\n    ...     execute_options={\"parameters\": (30,)},\n    ... )  # doctest: +SKIP\n\n    Or pass multiple parameters:\n\n    >>> df = pl.read_database_uri(\n    ...     \"SELECT * FROM employees WHERE hourly_rate BETWEEN ? AND ?\",\n    ...     \"sqlite:///:memory:\",\n    ...     engine=\"adbc\",\n    ...     execute_options={\"parameters\": (40, 20)},\n    ... )  # doctest: +SKIP\n    \"\"\"\n    from polars.io.database._utils import _read_sql_adbc, _read_sql_connectorx\n\n    if not isinstance(uri, str):\n        msg = f\"expected connection to be a URI string; found {qualified_type_name(uri)!r}\"\n        raise TypeError(msg)\n    elif engine is None:\n        engine = \"connectorx\"\n\n    if engine == \"connectorx\":\n        if execute_options:\n            msg = \"the 'connectorx' engine does not support use of `execute_options`\"\n            raise ValueError(msg)\n        if pre_execution_query:\n            issue_unstable_warning(\n                \"the 'pre-execution-query' parameter is considered unstable.\"\n            )\n        return _read_sql_connectorx(\n            query,\n            connection_uri=uri,\n            partition_on=partition_on,\n            partition_range=partition_range,\n            partition_num=partition_num,\n            protocol=protocol,","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/database/functions.py#L477-L513","documentation":"Raised by read_database_uri() when the uri argument is not a str. The URI-based reader is string-only; passing an engine, connection object, cursor, or None is a type error, reported with the qualified type name of what was actually received.","triggerScenarios":"pl.read_database_uri(query, engine_obj) or passing a SQLAlchemy Engine/Connection where the URI string belongs; argument order swaps (passing execute_options or engine in the uri slot).","commonSituations":"Mixed codebases using both read_database and read_database_uri; refactoring that changed what a variable holds; positional-argument mixups.","solutions":["Pass the URI as a string: pl.read_database_uri(query, 'postgresql://host/db')","If you hold a connection object, call pl.read_database(query, connection) instead","Check argument order — uri is the second positional parameter"],"exampleFix":"# before\npl.read_database_uri(q, sqlalchemy_engine)\n\n# after\npl.read_database_uri(q, \"postgresql://user:pw@host/db\")\n# or, with an engine object\npl.read_database(q, sqlalchemy_engine.connect())","handlingStrategy":"type-guard","validationCode":"if not isinstance(uri, str):\n    uri = str(uri)  # or raise early with your own message","typeGuard":"def is_uri_string(value: object) -> TypeGuard[str]:\n    return isinstance(value, str)","tryCatchPattern":null,"preventionTips":["Annotate helper params as uri: str vs connection: object to catch this statically","Never pass an Engine where a URI string is documented","Use keyword arguments (query=, uri=) to avoid positional mixups"],"tags":["database","type-error","api-misuse","uri"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}