Skip to content

Commit

Permalink
feat(python)!: Removal of read_database_uri passthrough from `read_…
Browse files Browse the repository at this point in the history
…database` (#16783)
  • Loading branch information
alexander-beedie authored Jun 6, 2024
1 parent d54e076 commit 90505af
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 47 deletions.
46 changes: 12 additions & 34 deletions py-polars/polars/io/database/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
import re
from typing import TYPE_CHECKING, Any, Iterable, Literal, overload

from polars._utils.deprecation import issue_deprecation_warning
from polars.datatypes import N_INFER_DEFAULT
from polars.dependencies import import_optional
from polars.exceptions import InvalidOperationError
from polars.io.database._cursor_proxies import ODBCCursorProxy
from polars.io.database._executor import ConnectionExecutor

Expand Down Expand Up @@ -37,7 +35,6 @@ def read_database(
schema_overrides: SchemaDict | None = ...,
infer_schema_length: int | None = ...,
execute_options: dict[str, Any] | None = ...,
**kwargs: Any,
) -> DataFrame: ...


Expand All @@ -51,7 +48,6 @@ def read_database(
schema_overrides: SchemaDict | None = ...,
infer_schema_length: int | None = ...,
execute_options: dict[str, Any] | None = ...,
**kwargs: Any,
) -> Iterable[DataFrame]: ...


Expand All @@ -65,11 +61,10 @@ def read_database(
schema_overrides: SchemaDict | None = ...,
infer_schema_length: int | None = ...,
execute_options: dict[str, Any] | None = ...,
**kwargs: Any,
) -> DataFrame | Iterable[DataFrame]: ...


def read_database( # noqa: D417
def read_database(
query: str | Selectable,
connection: ConnectionOrCursor | str,
*,
Expand All @@ -78,7 +73,6 @@ def read_database( # noqa: D417
schema_overrides: SchemaDict | None = None,
infer_schema_length: int | None = N_INFER_DEFAULT,
execute_options: dict[str, Any] | None = None,
**kwargs: Any,
) -> DataFrame | Iterable[DataFrame]:
"""
Read the results of a SQL query into a DataFrame, given a connection object.
Expand Down Expand Up @@ -147,17 +141,18 @@ def read_database( # noqa: D417
* The `read_database_uri` function can be noticeably faster than `read_database`
if you are using a SQLAlchemy or DBAPI2 connection, as `connectorx` and `adbc`
optimises translation of the result set into Arrow format. Note that you can
optimise translation of the result set into Arrow format. Note that you can
determine a connection's URI from a SQLAlchemy engine object by calling
`conn.engine.url.render_as_string(hide_password=False)`.
* If Polars has to create a cursor from your connection in order to execute the
query then that cursor will be automatically closed when the query completes;
however, Polars will *never* close any other open connection or cursor.
* We are able to support more than just relational databases and SQL queries
through this function. For example, we can load graph database results from
a `KùzuDB` connection in conjunction with a Cypher query.
* Polars is able to support more than just relational databases and SQL queries
through this function. For example, you can load local graph database results
from a `KùzuDB` connection in conjunction with a Cypher query, or use SurrealQL
with SurrealDB.
See Also
--------
Expand Down Expand Up @@ -245,30 +240,13 @@ def read_database( # noqa: D417
err_suffix="package",
)
connection = ODBCCursorProxy(connection)
elif "://" in connection:
# otherwise looks like a mistaken call to read_database_uri
msg = "Use of string URI is invalid here; call `read_database_uri` instead"
raise ValueError(msg)
else:
# otherwise looks like a call to read_database_uri
issue_deprecation_warning(
message="Use of a string URI with 'read_database' is deprecated; use `read_database_uri` instead",
version="0.19.0",
)
if iter_batches or batch_size:
msg = "Batch parameters are not supported for `read_database_uri`"
raise InvalidOperationError(msg)
if not isinstance(query, (list, str)):
msg = f"`read_database_uri` expects one or more string queries; found {type(query)}"
raise TypeError(msg)
return read_database_uri(
query,
uri=connection,
schema_overrides=schema_overrides,
**kwargs,
)

# note: can remove this check (and **kwargs) once we drop the
# pass-through deprecation support for read_database_uri
if kwargs:
msg = f"`read_database` **kwargs only exist for passthrough to `read_database_uri`: found {kwargs!r}"
raise ValueError(msg)
msg = "unable to identify string connection as valid ODBC (no driver)"
raise ValueError(msg)

# return frame from arbitrary connections using the executor abstraction
with ConnectionExecutor(connection) as cx:
Expand Down
26 changes: 13 additions & 13 deletions py-polars/tests/unit/io/database/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,17 +593,6 @@ def test_read_database_mocked(
),
id="Invalid statement type",
),
pytest.param(
*ExceptionTestParams(
read_method="read_database",
query="SELECT * FROM test_data",
protocol=sqlite3.connect(":memory:"),
errclass=ValueError,
errmsg=r"`read_database` \*\*kwargs only exist for passthrough to `read_database_uri`",
kwargs={"partition_on": "id"},
),
id="Invalid kwargs",
),
pytest.param(
*ExceptionTestParams(
read_method="read_database",
Expand All @@ -621,12 +610,23 @@ def test_read_database_mocked(
engine="adbc",
query="SELECT * FROM test_data",
protocol=sqlite3.connect(":memory:"),
errclass=ValueError,
errmsg=r"`read_database` \*\*kwargs only exist for passthrough to `read_database_uri`",
errclass=TypeError,
errmsg=r"unexpected keyword argument 'partition_on'",
kwargs={"partition_on": "id"},
),
id="Invalid kwargs",
),
pytest.param(
*ExceptionTestParams(
read_method="read_database",
engine="adbc",
query="SELECT * FROM test_data",
protocol="{not:a, valid:odbc_string}",
errclass=ValueError,
errmsg=r"unable to identify string connection as valid ODBC",
),
id="Invalid ODBC string",
),
],
)
def test_read_database_exceptions(
Expand Down

0 comments on commit 90505af

Please sign in to comment.