PyAthena 3.28.0__tar.gz → 3.29.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyathena-3.28.0 → pyathena-3.29.1}/PKG-INFO +19 -1
- {pyathena-3.28.0 → pyathena-3.29.1}/README.md +16 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/__init__.py +30 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/_version.py +2 -2
- pyathena-3.29.1/pyathena/aio/arrow/cursor.py +230 -0
- pyathena-3.29.1/pyathena/aio/common.py +500 -0
- pyathena-3.29.1/pyathena/aio/connection.py +54 -0
- pyathena-3.29.1/pyathena/aio/cursor.py +204 -0
- pyathena-3.29.1/pyathena/aio/pandas/cursor.py +251 -0
- pyathena-3.29.1/pyathena/aio/polars/cursor.py +238 -0
- pyathena-3.29.1/pyathena/aio/result_set.py +203 -0
- pyathena-3.29.1/pyathena/aio/s3fs/cursor.py +200 -0
- pyathena-3.29.1/pyathena/aio/spark/__init__.py +1 -0
- pyathena-3.29.1/pyathena/aio/spark/cursor.py +285 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/__init__.py +1 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/arrow.py +55 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/base.py +221 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/pandas.py +61 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/polars.py +55 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/rest.py +37 -0
- pyathena-3.29.1/pyathena/aio/sqlalchemy/s3fs.py +44 -0
- pyathena-3.29.1/pyathena/aio/util.py +33 -0
- pyathena-3.29.1/pyathena/arrow/__init__.py +1 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/arrow/async_cursor.py +2 -13
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/arrow/cursor.py +6 -98
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/async_cursor.py +1 -2
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/common.py +70 -10
- pyathena-3.29.1/pyathena/cursor.py +181 -0
- pyathena-3.29.1/pyathena/filesystem/__init__.py +1 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/formatter.py +2 -2
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/pandas/async_cursor.py +2 -13
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/pandas/cursor.py +4 -98
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/polars/async_cursor.py +2 -13
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/polars/cursor.py +5 -152
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/result_set.py +140 -2
- pyathena-3.29.1/pyathena/s3fs/__init__.py +1 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/s3fs/cursor.py +5 -140
- pyathena-3.29.1/pyathena/spark/__init__.py +1 -0
- pyathena-3.29.1/pyathena/sqlalchemy/__init__.py +1 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/compiler.py +65 -69
- {pyathena-3.28.0 → pyathena-3.29.1}/pyproject.toml +13 -1
- pyathena-3.28.0/pyathena/cursor.py +0 -394
- {pyathena-3.28.0 → pyathena-3.29.1}/.gitignore +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/LICENSE +0 -0
- {pyathena-3.28.0/pyathena/arrow → pyathena-3.29.1/pyathena/aio}/__init__.py +0 -0
- {pyathena-3.28.0/pyathena/filesystem → pyathena-3.29.1/pyathena/aio/arrow}/__init__.py +0 -0
- {pyathena-3.28.0/pyathena/s3fs → pyathena-3.29.1/pyathena/aio/pandas}/__init__.py +0 -0
- {pyathena-3.28.0/pyathena/spark → pyathena-3.29.1/pyathena/aio/polars}/__init__.py +0 -0
- {pyathena-3.28.0/pyathena/sqlalchemy → pyathena-3.29.1/pyathena/aio/s3fs}/__init__.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/arrow/converter.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/arrow/result_set.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/arrow/util.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/connection.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/converter.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/error.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/filesystem/s3.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/filesystem/s3_object.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/model.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/pandas/__init__.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/pandas/converter.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/pandas/result_set.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/pandas/util.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/polars/__init__.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/polars/converter.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/polars/result_set.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/polars/util.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/py.typed +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/s3fs/async_cursor.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/s3fs/converter.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/s3fs/reader.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/s3fs/result_set.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/spark/async_cursor.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/spark/common.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/spark/cursor.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/arrow.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/base.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/constants.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/pandas.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/polars.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/preparer.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/requirements.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/rest.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/s3fs.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/types.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/sqlalchemy/util.py +0 -0
- {pyathena-3.28.0 → pyathena-3.29.1}/pyathena/util.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyAthena
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.29.1
|
|
4
4
|
Summary: Python DB API 2.0 (PEP 249) client for Amazon Athena
|
|
5
5
|
Project-URL: homepage, https://github.com/pyathena-dev/PyAthena/
|
|
6
6
|
Project-URL: repository, https://github.com/pyathena-dev/PyAthena/
|
|
@@ -43,6 +43,8 @@ Requires-Dist: botocore>=1.29.4
|
|
|
43
43
|
Requires-Dist: fsspec
|
|
44
44
|
Requires-Dist: python-dateutil
|
|
45
45
|
Requires-Dist: tenacity>=4.1.0
|
|
46
|
+
Provides-Extra: aiosqlalchemy
|
|
47
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.0; extra == 'aiosqlalchemy'
|
|
46
48
|
Provides-Extra: arrow
|
|
47
49
|
Requires-Dist: pyarrow>=10.0.0; (python_version < '3.14') and extra == 'arrow'
|
|
48
50
|
Requires-Dist: pyarrow>=22.0.0; (python_version >= '3.14') and extra == 'arrow'
|
|
@@ -109,6 +111,22 @@ print(cursor.description)
|
|
|
109
111
|
print(cursor.fetchall())
|
|
110
112
|
```
|
|
111
113
|
|
|
114
|
+
Native asyncio is also supported:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import asyncio
|
|
118
|
+
from pyathena import aconnect
|
|
119
|
+
|
|
120
|
+
async def main():
|
|
121
|
+
async with await aconnect(s3_staging_dir="s3://YOUR_S3_BUCKET/path/to/",
|
|
122
|
+
region_name="us-west-2") as conn:
|
|
123
|
+
cursor = conn.cursor()
|
|
124
|
+
await cursor.execute("SELECT 1")
|
|
125
|
+
print(await cursor.fetchone())
|
|
126
|
+
|
|
127
|
+
asyncio.run(main())
|
|
128
|
+
```
|
|
129
|
+
|
|
112
130
|
## License
|
|
113
131
|
|
|
114
132
|
[MIT license](LICENSE)
|
|
@@ -52,6 +52,22 @@ print(cursor.description)
|
|
|
52
52
|
print(cursor.fetchall())
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
Native asyncio is also supported:
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import asyncio
|
|
59
|
+
from pyathena import aconnect
|
|
60
|
+
|
|
61
|
+
async def main():
|
|
62
|
+
async with await aconnect(s3_staging_dir="s3://YOUR_S3_BUCKET/path/to/",
|
|
63
|
+
region_name="us-west-2") as conn:
|
|
64
|
+
cursor = conn.cursor()
|
|
65
|
+
await cursor.execute("SELECT 1")
|
|
66
|
+
print(await cursor.fetchone())
|
|
67
|
+
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
55
71
|
## License
|
|
56
72
|
|
|
57
73
|
[MIT license](LICENSE)
|
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Any, FrozenSet, Type, overload
|
|
|
7
7
|
from pyathena.error import * # noqa
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
+
from pyathena.aio.connection import AioConnection
|
|
10
11
|
from pyathena.connection import Connection, ConnectionCursor
|
|
11
12
|
from pyathena.cursor import Cursor
|
|
12
13
|
|
|
@@ -128,3 +129,32 @@ def connect(*args, **kwargs) -> "Connection[Any]":
|
|
|
128
129
|
from pyathena.connection import Connection
|
|
129
130
|
|
|
130
131
|
return Connection(*args, **kwargs)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
async def aconnect(*args, **kwargs) -> "AioConnection":
|
|
135
|
+
"""Create a new async database connection to Amazon Athena.
|
|
136
|
+
|
|
137
|
+
This is the async counterpart of :func:`connect`. It returns an
|
|
138
|
+
``AioConnection`` whose cursors use native ``asyncio`` for polling
|
|
139
|
+
and API calls, keeping the event loop free.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
**kwargs: Arguments forwarded to ``AioConnection.create()``.
|
|
143
|
+
See :func:`connect` for the full list of supported arguments.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
An ``AioConnection`` that produces ``AioCursor`` instances by default.
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
>>> import pyathena
|
|
150
|
+
>>> conn = await pyathena.aconnect(
|
|
151
|
+
... s3_staging_dir='s3://my-bucket/staging/',
|
|
152
|
+
... region_name='us-east-1',
|
|
153
|
+
... )
|
|
154
|
+
>>> async with conn.cursor() as cursor:
|
|
155
|
+
... await cursor.execute("SELECT 1")
|
|
156
|
+
... print(await cursor.fetchone())
|
|
157
|
+
"""
|
|
158
|
+
from pyathena.aio.connection import AioConnection
|
|
159
|
+
|
|
160
|
+
return await AioConnection.create(*args, **kwargs)
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '3.
|
|
32
|
-
__version_tuple__ = version_tuple = (3,
|
|
31
|
+
__version__ = version = '3.29.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (3, 29, 1)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import asyncio
|
|
5
|
+
import logging
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union, cast
|
|
7
|
+
|
|
8
|
+
from pyathena.aio.common import WithAsyncFetch
|
|
9
|
+
from pyathena.arrow.converter import (
|
|
10
|
+
DefaultArrowTypeConverter,
|
|
11
|
+
DefaultArrowUnloadTypeConverter,
|
|
12
|
+
)
|
|
13
|
+
from pyathena.arrow.result_set import AthenaArrowResultSet
|
|
14
|
+
from pyathena.common import CursorIterator
|
|
15
|
+
from pyathena.error import OperationalError, ProgrammingError
|
|
16
|
+
from pyathena.model import AthenaQueryExecution
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
import polars as pl
|
|
20
|
+
from pyarrow import Table
|
|
21
|
+
|
|
22
|
+
_logger = logging.getLogger(__name__) # type: ignore
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AioArrowCursor(WithAsyncFetch):
|
|
26
|
+
"""Native asyncio cursor that returns results as Apache Arrow Tables.
|
|
27
|
+
|
|
28
|
+
Uses ``asyncio.to_thread()`` for both result set creation and fetch
|
|
29
|
+
operations, keeping the event loop free.
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
>>> async with await pyathena.aconnect(...) as conn:
|
|
33
|
+
... cursor = conn.cursor(AioArrowCursor)
|
|
34
|
+
... await cursor.execute("SELECT * FROM my_table")
|
|
35
|
+
... table = cursor.as_arrow()
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
s3_staging_dir: Optional[str] = None,
|
|
41
|
+
schema_name: Optional[str] = None,
|
|
42
|
+
catalog_name: Optional[str] = None,
|
|
43
|
+
work_group: Optional[str] = None,
|
|
44
|
+
poll_interval: float = 1,
|
|
45
|
+
encryption_option: Optional[str] = None,
|
|
46
|
+
kms_key: Optional[str] = None,
|
|
47
|
+
kill_on_interrupt: bool = True,
|
|
48
|
+
unload: bool = False,
|
|
49
|
+
result_reuse_enable: bool = False,
|
|
50
|
+
result_reuse_minutes: int = CursorIterator.DEFAULT_RESULT_REUSE_MINUTES,
|
|
51
|
+
connect_timeout: Optional[float] = None,
|
|
52
|
+
request_timeout: Optional[float] = None,
|
|
53
|
+
**kwargs,
|
|
54
|
+
) -> None:
|
|
55
|
+
super().__init__(
|
|
56
|
+
s3_staging_dir=s3_staging_dir,
|
|
57
|
+
schema_name=schema_name,
|
|
58
|
+
catalog_name=catalog_name,
|
|
59
|
+
work_group=work_group,
|
|
60
|
+
poll_interval=poll_interval,
|
|
61
|
+
encryption_option=encryption_option,
|
|
62
|
+
kms_key=kms_key,
|
|
63
|
+
kill_on_interrupt=kill_on_interrupt,
|
|
64
|
+
result_reuse_enable=result_reuse_enable,
|
|
65
|
+
result_reuse_minutes=result_reuse_minutes,
|
|
66
|
+
**kwargs,
|
|
67
|
+
)
|
|
68
|
+
self._unload = unload
|
|
69
|
+
self._connect_timeout = connect_timeout
|
|
70
|
+
self._request_timeout = request_timeout
|
|
71
|
+
self._result_set: Optional[AthenaArrowResultSet] = None
|
|
72
|
+
|
|
73
|
+
@staticmethod
|
|
74
|
+
def get_default_converter(
|
|
75
|
+
unload: bool = False,
|
|
76
|
+
) -> Union[DefaultArrowTypeConverter, DefaultArrowUnloadTypeConverter, Any]:
|
|
77
|
+
if unload:
|
|
78
|
+
return DefaultArrowUnloadTypeConverter()
|
|
79
|
+
return DefaultArrowTypeConverter()
|
|
80
|
+
|
|
81
|
+
async def execute( # type: ignore[override]
|
|
82
|
+
self,
|
|
83
|
+
operation: str,
|
|
84
|
+
parameters: Optional[Union[Dict[str, Any], List[str]]] = None,
|
|
85
|
+
work_group: Optional[str] = None,
|
|
86
|
+
s3_staging_dir: Optional[str] = None,
|
|
87
|
+
cache_size: Optional[int] = 0,
|
|
88
|
+
cache_expiration_time: Optional[int] = 0,
|
|
89
|
+
result_reuse_enable: Optional[bool] = None,
|
|
90
|
+
result_reuse_minutes: Optional[int] = None,
|
|
91
|
+
paramstyle: Optional[str] = None,
|
|
92
|
+
**kwargs,
|
|
93
|
+
) -> "AioArrowCursor":
|
|
94
|
+
"""Execute a SQL query asynchronously and return results as Arrow Tables.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
operation: SQL query string to execute.
|
|
98
|
+
parameters: Query parameters for parameterized queries.
|
|
99
|
+
work_group: Athena workgroup to use for this query.
|
|
100
|
+
s3_staging_dir: S3 location for query results.
|
|
101
|
+
cache_size: Number of queries to check for result caching.
|
|
102
|
+
cache_expiration_time: Cache expiration time in seconds.
|
|
103
|
+
result_reuse_enable: Enable Athena result reuse for this query.
|
|
104
|
+
result_reuse_minutes: Minutes to reuse cached results.
|
|
105
|
+
paramstyle: Parameter style ('qmark' or 'pyformat').
|
|
106
|
+
**kwargs: Additional execution parameters.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Self reference for method chaining.
|
|
110
|
+
"""
|
|
111
|
+
self._reset_state()
|
|
112
|
+
operation, unload_location = self._prepare_unload(operation, s3_staging_dir)
|
|
113
|
+
self.query_id = await self._execute(
|
|
114
|
+
operation,
|
|
115
|
+
parameters=parameters,
|
|
116
|
+
work_group=work_group,
|
|
117
|
+
s3_staging_dir=s3_staging_dir,
|
|
118
|
+
cache_size=cache_size,
|
|
119
|
+
cache_expiration_time=cache_expiration_time,
|
|
120
|
+
result_reuse_enable=result_reuse_enable,
|
|
121
|
+
result_reuse_minutes=result_reuse_minutes,
|
|
122
|
+
paramstyle=paramstyle,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
query_execution = await self._poll(self.query_id)
|
|
126
|
+
if query_execution.state == AthenaQueryExecution.STATE_SUCCEEDED:
|
|
127
|
+
self.result_set = await asyncio.to_thread(
|
|
128
|
+
AthenaArrowResultSet,
|
|
129
|
+
connection=self._connection,
|
|
130
|
+
converter=self._converter,
|
|
131
|
+
query_execution=query_execution,
|
|
132
|
+
arraysize=self.arraysize,
|
|
133
|
+
retry_config=self._retry_config,
|
|
134
|
+
unload=self._unload,
|
|
135
|
+
unload_location=unload_location,
|
|
136
|
+
connect_timeout=self._connect_timeout,
|
|
137
|
+
request_timeout=self._request_timeout,
|
|
138
|
+
**kwargs,
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
raise OperationalError(query_execution.state_change_reason)
|
|
142
|
+
return self
|
|
143
|
+
|
|
144
|
+
async def fetchone( # type: ignore[override]
|
|
145
|
+
self,
|
|
146
|
+
) -> Optional[Union[Tuple[Optional[Any], ...], Dict[Any, Optional[Any]]]]:
|
|
147
|
+
"""Fetch the next row of the result set.
|
|
148
|
+
|
|
149
|
+
Wraps the synchronous fetch in ``asyncio.to_thread`` to avoid
|
|
150
|
+
blocking the event loop.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
A tuple representing the next row, or None if no more rows.
|
|
154
|
+
|
|
155
|
+
Raises:
|
|
156
|
+
ProgrammingError: If no result set is available.
|
|
157
|
+
"""
|
|
158
|
+
if not self.has_result_set:
|
|
159
|
+
raise ProgrammingError("No result set.")
|
|
160
|
+
result_set = cast(AthenaArrowResultSet, self.result_set)
|
|
161
|
+
return await asyncio.to_thread(result_set.fetchone)
|
|
162
|
+
|
|
163
|
+
async def fetchmany( # type: ignore[override]
|
|
164
|
+
self, size: Optional[int] = None
|
|
165
|
+
) -> List[Union[Tuple[Optional[Any], ...], Dict[Any, Optional[Any]]]]:
|
|
166
|
+
"""Fetch multiple rows from the result set.
|
|
167
|
+
|
|
168
|
+
Wraps the synchronous fetch in ``asyncio.to_thread`` to avoid
|
|
169
|
+
blocking the event loop.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
size: Maximum number of rows to fetch. Defaults to arraysize.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
List of tuples representing the fetched rows.
|
|
176
|
+
|
|
177
|
+
Raises:
|
|
178
|
+
ProgrammingError: If no result set is available.
|
|
179
|
+
"""
|
|
180
|
+
if not self.has_result_set:
|
|
181
|
+
raise ProgrammingError("No result set.")
|
|
182
|
+
result_set = cast(AthenaArrowResultSet, self.result_set)
|
|
183
|
+
return await asyncio.to_thread(result_set.fetchmany, size)
|
|
184
|
+
|
|
185
|
+
async def fetchall( # type: ignore[override]
|
|
186
|
+
self,
|
|
187
|
+
) -> List[Union[Tuple[Optional[Any], ...], Dict[Any, Optional[Any]]]]:
|
|
188
|
+
"""Fetch all remaining rows from the result set.
|
|
189
|
+
|
|
190
|
+
Wraps the synchronous fetch in ``asyncio.to_thread`` to avoid
|
|
191
|
+
blocking the event loop.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
List of tuples representing all remaining rows.
|
|
195
|
+
|
|
196
|
+
Raises:
|
|
197
|
+
ProgrammingError: If no result set is available.
|
|
198
|
+
"""
|
|
199
|
+
if not self.has_result_set:
|
|
200
|
+
raise ProgrammingError("No result set.")
|
|
201
|
+
result_set = cast(AthenaArrowResultSet, self.result_set)
|
|
202
|
+
return await asyncio.to_thread(result_set.fetchall)
|
|
203
|
+
|
|
204
|
+
async def __anext__(self):
|
|
205
|
+
row = await self.fetchone()
|
|
206
|
+
if row is None:
|
|
207
|
+
raise StopAsyncIteration
|
|
208
|
+
return row
|
|
209
|
+
|
|
210
|
+
def as_arrow(self) -> "Table":
|
|
211
|
+
"""Return query results as an Apache Arrow Table.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
Apache Arrow Table containing all query results.
|
|
215
|
+
"""
|
|
216
|
+
if not self.has_result_set:
|
|
217
|
+
raise ProgrammingError("No result set.")
|
|
218
|
+
result_set = cast(AthenaArrowResultSet, self.result_set)
|
|
219
|
+
return result_set.as_arrow()
|
|
220
|
+
|
|
221
|
+
def as_polars(self) -> "pl.DataFrame":
|
|
222
|
+
"""Return query results as a Polars DataFrame.
|
|
223
|
+
|
|
224
|
+
Returns:
|
|
225
|
+
Polars DataFrame containing all query results.
|
|
226
|
+
"""
|
|
227
|
+
if not self.has_result_set:
|
|
228
|
+
raise ProgrammingError("No result set.")
|
|
229
|
+
result_set = cast(AthenaArrowResultSet, self.result_set)
|
|
230
|
+
return result_set.as_polars()
|