1717
1818if TYPE_CHECKING :
1919 import pandas as pd
20+ import polars as pl
2021 import pyarrow as pa
2122 import pyspark
2223 import requests
@@ -35,7 +36,7 @@ def query_foundry_sql(
3536 branch : Ref = ...,
3637 sql_dialect : SqlDialect = ...,
3738 timeout : int = ...,
38- ) -> pd .core . frame . DataFrame : ...
39+ ) -> pd .DataFrame : ...
3940
4041 @overload
4142 def query_foundry_sql (
@@ -57,6 +58,16 @@ def query_foundry_sql(
5758 timeout : int = ...,
5859 ) -> pa .Table : ...
5960
61+ @overload
62+ def query_foundry_sql (
63+ self ,
64+ query : str ,
65+ return_type : Literal ["polars" ],
66+ branch : Ref = ...,
67+ sql_dialect : SqlDialect = ...,
68+ timeout : int = ...,
69+ ) -> pl .DataFrame : ...
70+
6071 @overload
6172 def query_foundry_sql (
6273 self ,
@@ -75,16 +86,16 @@ def query_foundry_sql(
7586 branch : Ref = ...,
7687 sql_dialect : SqlDialect = ...,
7788 timeout : int = ...,
78- ) -> tuple [dict , list [list ]] | pd .core . frame .DataFrame | pa .Table | pyspark .sql .DataFrame : ...
89+ ) -> tuple [dict , list [list ]] | pd .DataFrame | pl .DataFrame | pa .Table | pyspark .sql .DataFrame : ...
7990
80- def query_foundry_sql (
91+ def query_foundry_sql ( # noqa: C901
8192 self ,
8293 query : str ,
8394 return_type : SQLReturnType = "pandas" ,
8495 branch : Ref = "master" ,
8596 sql_dialect : SqlDialect = "SPARK" ,
8697 timeout : int = 600 ,
87- ) -> tuple [dict , list [list ]] | pd .core . frame .DataFrame | pa .Table | pyspark .sql .DataFrame :
98+ ) -> tuple [dict , list [list ]] | pd .DataFrame | pl .DataFrame | pa .Table | pyspark .sql .DataFrame :
8899 """Queries the Foundry SQL server with spark SQL dialect.
89100
90101 Uses Arrow IPC to communicate with the Foundry SQL Server Endpoint.
@@ -105,9 +116,9 @@ def query_foundry_sql(
105116 timeout: Query Timeout, default value is 600 seconds
106117
107118 Returns:
108- :external+pandas:py:class:`~pandas.DataFrame` | :external+pyarrow:py:class:`~pyarrow.Table` | :external+spark:py:class:`~pyspark.sql.DataFrame`:
119+ :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`:
109120
110- A pandas DataFrame , Spark DataFrame or pyarrow.Table with the result.
121+ A pandas, polars , Spark DataFrame or pyarrow.Table with the result.
111122
112123 Raises:
113124 ValueError: Only direct read eligible queries can be returned as arrow Table.
@@ -139,6 +150,15 @@ def query_foundry_sql(
139150 arrow_stream_reader = self .read_fsql_query_results_arrow (query_id = query_id )
140151 if return_type == "pandas" :
141152 return arrow_stream_reader .read_pandas ()
153+ if return_type == "polars" :
154+ # The FakeModule implementation used in the _optional packages
155+ # throws an ImportError when trying to access attributes of the module.
156+ # This ImportError is caught below to fall back to query_foundry_sql_legacy
157+ # which will again raise an ImportError when polars is not installed.
158+ from foundry_dev_tools ._optional .polars import pl
159+
160+ arrow_table = arrow_stream_reader .read_all ()
161+ return pl .from_arrow (arrow_table )
142162
143163 if return_type == "spark" :
144164 from foundry_dev_tools .utils .converter .foundry_spark import (
@@ -147,16 +167,12 @@ def query_foundry_sql(
147167
148168 return arrow_stream_to_spark_dataframe (arrow_stream_reader )
149169 return arrow_stream_reader .read_all ()
150-
151- return self ._query_fsql (
152- query = query ,
153- branch = branch ,
154- return_type = return_type ,
155- )
156170 except (
157171 FoundrySqlSerializationFormatNotImplementedError ,
158172 ImportError ,
159173 ) as exc :
174+ # Swallow exception when return_type != 'arrow'
175+ # to fall back to query_foundry_sql_legacy
160176 if return_type == "arrow" :
161177 msg = (
162178 "Only direct read eligible queries can be returned as arrow Table. Consider using setting"
@@ -166,6 +182,8 @@ def query_foundry_sql(
166182 msg ,
167183 ) from exc
168184
185+ # this fallback is not only used if return_type is 'raw', but also when one of
186+ # the above exceptions is caught and return_type != 'arrow'
169187 warnings .warn ("Falling back to query_foundry_sql_legacy!" )
170188 return self .context .data_proxy .query_foundry_sql_legacy (
171189 query = query ,
0 commit comments