Skip to content

Commit 7ea48a9

Browse files
committed
support polars in v2 as well.
1 parent d02d515 commit 7ea48a9

2 files changed

Lines changed: 34 additions & 4 deletions

File tree

libs/foundry-dev-tools/src/foundry_dev_tools/clients/foundry_sql_server.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,16 @@ def query_foundry_sql(
322322
timeout: int = ...,
323323
) -> pd.core.frame.DataFrame: ...
324324

325+
@overload
326+
def query_foundry_sql(
327+
self,
328+
query: str,
329+
return_type: Literal["polars"],
330+
branch: Ref = ...,
331+
sql_dialect: SqlDialect = ...,
332+
timeout: int = ...,
333+
) -> pl.DataFrame: ...
334+
325335
@overload
326336
def query_foundry_sql(
327337
self,
@@ -350,15 +360,15 @@ def query_foundry_sql(
350360
return_type: SQLReturnType = ...,
351361
disable_arrow_compression: bool = ...,
352362
timeout: int = ...,
353-
) -> tuple[dict, list[list]] | pd.core.frame.DataFrame | pa.Table | pyspark.sql.DataFrame: ...
363+
) -> tuple[dict, list[list]] | pd.core.frame.DataFrame | pl.DataFrame | pa.Table | pyspark.sql.DataFrame: ...
354364

355365
def query_foundry_sql(
356366
self,
357367
query: str,
358368
return_type: SQLReturnType = "pandas",
359369
disable_arrow_compression: bool = False,
360370
application_id: str | None = None,
361-
) -> tuple[dict, list[list]] | pd.core.frame.DataFrame | pa.Table | pyspark.sql.DataFrame:
371+
) -> tuple[dict, list[list]] | pd.core.frame.DataFrame | pl.DataFrame | pa.Table | pyspark.sql.DataFrame:
362372
"""Queries the Foundry SQL server using the V2 API.
363373
364374
Uses Arrow IPC to communicate with the Foundry SQL Server Endpoint.
@@ -376,9 +386,9 @@ def query_foundry_sql(
376386
application_id: The application/dataset RID, defaults to foundry-dev-tools User-Agent
377387
378388
Returns:
379-
:external+pandas:py:class:`~pandas.DataFrame` | :external+pyarrow:py:class:`~pyarrow.Table` | :external+spark:py:class:`~pyspark.sql.DataFrame`:
389+
:external+pandas:py:class:`~pandas.DataFrame` | :external+polars:py:class:`~polars.DataFrame` | :external+pyarrow:py:class:`~pyarrow.Table` | :external+spark:py:class:`~pyspark.sql.DataFrame`:
380390
381-
A pandas DataFrame, Spark DataFrame or pyarrow.Table with the result.
391+
A pandas DataFrame, polars, Spark DataFrame or pyarrow.Table with the result.
382392
383393
Raises:
384394
FoundrySqlQueryFailedError: If the query fails
@@ -414,6 +424,16 @@ def query_foundry_sql(
414424
if return_type == "pandas":
415425
return arrow_stream_reader.read_pandas()
416426

427+
if return_type == "polars":
428+
# The FakeModule implementation used in the _optional packages
429+
# throws an ImportError when trying to access attributes of the module.
430+
# This ImportError is caught below to fall back to query_foundry_sql_legacy
431+
# which will again raise an ImportError when polars is not installed.
432+
from foundry_dev_tools._optional.polars import pl
433+
434+
arrow_table = arrow_stream_reader.read_all()
435+
return pl.from_arrow(arrow_table)
436+
417437
if return_type == "spark":
418438
from foundry_dev_tools.utils.converter.foundry_spark import (
419439
arrow_stream_to_spark_dataframe,

tests/integration/clients/test_foundry_sql_server.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,13 @@ def test_v2_with_where_clause():
176176
# Verify all returned rows have is_setosa = 'setosa'
177177
if result.shape[0] > 0:
178178
assert all(result["is_setosa"] == "setosa")
179+
180+
181+
def test_v2_polars_return_type():
182+
polars_df = TEST_SINGLETON.ctx.foundry_sql_server_v2.query_foundry_sql(
183+
f"SELECT sepal_length FROM `{TEST_SINGLETON.iris_new.rid}` LIMIT 2",
184+
return_type="polars",
185+
)
186+
assert isinstance(polars_df, pl.DataFrame)
187+
assert polars_df.height == 2
188+
assert polars_df.width == 1

0 commit comments

Comments
 (0)