snowflake-connector-python 3.16.0__cp313-cp313-win_amd64.whl
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.
- snowflake/connector/__init__.py +96 -0
- snowflake/connector/_query_context_cache.py +276 -0
- snowflake/connector/_sql_util.py +48 -0
- snowflake/connector/_utils.py +70 -0
- snowflake/connector/arrow_context.py +203 -0
- snowflake/connector/auth/__init__.py +53 -0
- snowflake/connector/auth/_auth.py +586 -0
- snowflake/connector/auth/_http_server.py +220 -0
- snowflake/connector/auth/_oauth_base.py +400 -0
- snowflake/connector/auth/by_plugin.py +219 -0
- snowflake/connector/auth/default.py +36 -0
- snowflake/connector/auth/idtoken.py +72 -0
- snowflake/connector/auth/keypair.py +222 -0
- snowflake/connector/auth/no_auth.py +39 -0
- snowflake/connector/auth/oauth.py +49 -0
- snowflake/connector/auth/oauth_code.py +479 -0
- snowflake/connector/auth/oauth_credentials.py +66 -0
- snowflake/connector/auth/okta.py +335 -0
- snowflake/connector/auth/pat.py +39 -0
- snowflake/connector/auth/usrpwdmfa.py +69 -0
- snowflake/connector/auth/webbrowser.py +502 -0
- snowflake/connector/auth/workload_identity.py +94 -0
- snowflake/connector/azure_storage_client.py +276 -0
- snowflake/connector/backoff_policies.py +141 -0
- snowflake/connector/bind_upload_agent.py +89 -0
- snowflake/connector/cache.py +696 -0
- snowflake/connector/compat.py +127 -0
- snowflake/connector/config_manager.py +496 -0
- snowflake/connector/connection.py +2273 -0
- snowflake/connector/connection_diagnostic.py +776 -0
- snowflake/connector/constants.py +442 -0
- snowflake/connector/converter.py +785 -0
- snowflake/connector/converter_issue23517.py +87 -0
- snowflake/connector/converter_null.py +14 -0
- snowflake/connector/converter_snowsql.py +205 -0
- snowflake/connector/cursor.py +1951 -0
- snowflake/connector/dbapi.py +53 -0
- snowflake/connector/description.py +19 -0
- snowflake/connector/direct_file_operation_utils.py +88 -0
- snowflake/connector/encryption_util.py +220 -0
- snowflake/connector/errorcode.py +91 -0
- snowflake/connector/errors.py +615 -0
- snowflake/connector/externals_utils/__init__.py +0 -0
- snowflake/connector/externals_utils/externals_setup.py +27 -0
- snowflake/connector/feature.py +4 -0
- snowflake/connector/file_compression_type.py +118 -0
- snowflake/connector/file_lock.py +72 -0
- snowflake/connector/file_transfer_agent.py +1215 -0
- snowflake/connector/file_util.py +153 -0
- snowflake/connector/gcs_storage_client.py +474 -0
- snowflake/connector/gzip_decoder.py +85 -0
- snowflake/connector/local_storage_client.py +90 -0
- snowflake/connector/log_configuration.py +60 -0
- snowflake/connector/logging_utils/__init__.py +0 -0
- snowflake/connector/logging_utils/filters.py +72 -0
- snowflake/connector/nanoarrow_arrow_iterator.cp313-win_amd64.pyd +0 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +60 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.cpp +557 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowChunkIterator.hpp +98 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +115 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.cpp +1005 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/CArrowTableIterator.hpp +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +47 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +83 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +72 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +73 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +71 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +56 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +75 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +46 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +95 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +57 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +34 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +36 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +346 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +145 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +101 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +127 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1908 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +215 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +125 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +55 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +148 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +97 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +239 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +210 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +84 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +206 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +118 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +162 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +898 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +190 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/flatcc.c +3204 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3217 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3618 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +379 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_arrow_iterator.pyx +256 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.c +512 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_device.h +350 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +33273 -0
- snowflake/connector/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +397 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.cpp +100 -0
- snowflake/connector/nanoarrow_cpp/Logging/logging.hpp +49 -0
- snowflake/connector/network.py +1297 -0
- snowflake/connector/ocsp_asn1crypto.py +447 -0
- snowflake/connector/ocsp_snowflake.py +1883 -0
- snowflake/connector/options.py +131 -0
- snowflake/connector/pandas_tools.py +732 -0
- snowflake/connector/proxy.py +43 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +786 -0
- snowflake/connector/result_set.py +319 -0
- snowflake/connector/s3_storage_client.py +605 -0
- snowflake/connector/secret_detector.py +181 -0
- snowflake/connector/sf_dirs.py +64 -0
- snowflake/connector/sfbinaryformat.py +35 -0
- snowflake/connector/sfdatetime.py +345 -0
- snowflake/connector/snow_logging.py +144 -0
- snowflake/connector/sqlstate.py +9 -0
- snowflake/connector/ssd_internal_keys.py +30 -0
- snowflake/connector/ssl_wrap_socket.py +134 -0
- snowflake/connector/storage_client.py +478 -0
- snowflake/connector/telemetry.py +249 -0
- snowflake/connector/telemetry_oob.py +543 -0
- snowflake/connector/test_util.py +30 -0
- snowflake/connector/time_util.py +159 -0
- snowflake/connector/token_cache.py +402 -0
- snowflake/connector/tool/__init__.py +0 -0
- snowflake/connector/tool/dump_certs.py +57 -0
- snowflake/connector/tool/dump_ocsp_response.py +139 -0
- snowflake/connector/tool/dump_ocsp_response_cache.py +194 -0
- snowflake/connector/tool/probe_connection.py +69 -0
- snowflake/connector/url_util.py +49 -0
- snowflake/connector/util_text.py +301 -0
- snowflake/connector/vendored/__init__.py +3 -0
- snowflake/connector/vendored/requests/LICENSE +175 -0
- snowflake/connector/vendored/requests/__init__.py +169 -0
- snowflake/connector/vendored/requests/__version__.py +14 -0
- snowflake/connector/vendored/requests/_internal_utils.py +50 -0
- snowflake/connector/vendored/requests/adapters.py +537 -0
- snowflake/connector/vendored/requests/api.py +157 -0
- snowflake/connector/vendored/requests/auth.py +315 -0
- snowflake/connector/vendored/requests/certs.py +17 -0
- snowflake/connector/vendored/requests/compat.py +79 -0
- snowflake/connector/vendored/requests/cookies.py +561 -0
- snowflake/connector/vendored/requests/exceptions.py +140 -0
- snowflake/connector/vendored/requests/help.py +134 -0
- snowflake/connector/vendored/requests/hooks.py +33 -0
- snowflake/connector/vendored/requests/models.py +1033 -0
- snowflake/connector/vendored/requests/sessions.py +833 -0
- snowflake/connector/vendored/requests/status_codes.py +128 -0
- snowflake/connector/vendored/requests/structures.py +99 -0
- snowflake/connector/vendored/requests/utils.py +1093 -0
- snowflake/connector/vendored/urllib3/LICENSE.txt +21 -0
- snowflake/connector/vendored/urllib3/__init__.py +85 -0
- snowflake/connector/vendored/urllib3/_collections.py +355 -0
- snowflake/connector/vendored/urllib3/_version.py +2 -0
- snowflake/connector/vendored/urllib3/connection.py +572 -0
- snowflake/connector/vendored/urllib3/connectionpool.py +1137 -0
- snowflake/connector/vendored/urllib3/contrib/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/_appengine_environ.py +36 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/bindings.py +519 -0
- snowflake/connector/vendored/urllib3/contrib/_securetransport/low_level.py +397 -0
- snowflake/connector/vendored/urllib3/contrib/appengine.py +314 -0
- snowflake/connector/vendored/urllib3/contrib/ntlmpool.py +130 -0
- snowflake/connector/vendored/urllib3/contrib/pyopenssl.py +509 -0
- snowflake/connector/vendored/urllib3/contrib/securetransport.py +920 -0
- snowflake/connector/vendored/urllib3/contrib/socks.py +216 -0
- snowflake/connector/vendored/urllib3/exceptions.py +323 -0
- snowflake/connector/vendored/urllib3/fields.py +274 -0
- snowflake/connector/vendored/urllib3/filepost.py +98 -0
- snowflake/connector/vendored/urllib3/packages/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/packages/backports/__init__.py +0 -0
- snowflake/connector/vendored/urllib3/packages/backports/makefile.py +51 -0
- snowflake/connector/vendored/urllib3/packages/backports/weakref_finalize.py +155 -0
- snowflake/connector/vendored/urllib3/packages/six.py +1076 -0
- snowflake/connector/vendored/urllib3/poolmanager.py +540 -0
- snowflake/connector/vendored/urllib3/request.py +191 -0
- snowflake/connector/vendored/urllib3/response.py +885 -0
- snowflake/connector/vendored/urllib3/util/__init__.py +49 -0
- snowflake/connector/vendored/urllib3/util/connection.py +156 -0
- snowflake/connector/vendored/urllib3/util/proxy.py +57 -0
- snowflake/connector/vendored/urllib3/util/queue.py +22 -0
- snowflake/connector/vendored/urllib3/util/request.py +146 -0
- snowflake/connector/vendored/urllib3/util/response.py +107 -0
- snowflake/connector/vendored/urllib3/util/retry.py +620 -0
- snowflake/connector/vendored/urllib3/util/ssl_.py +495 -0
- snowflake/connector/vendored/urllib3/util/ssl_match_hostname.py +159 -0
- snowflake/connector/vendored/urllib3/util/ssltransport.py +221 -0
- snowflake/connector/vendored/urllib3/util/timeout.py +271 -0
- snowflake/connector/vendored/urllib3/util/url.py +435 -0
- snowflake/connector/vendored/urllib3/util/wait.py +152 -0
- snowflake/connector/version.py +3 -0
- snowflake/connector/wif_util.py +407 -0
- snowflake_connector_python-3.16.0.dist-info/METADATA +1475 -0
- snowflake_connector_python-3.16.0.dist-info/RECORD +246 -0
- snowflake_connector_python-3.16.0.dist-info/WHEEL +5 -0
- snowflake_connector_python-3.16.0.dist-info/entry_points.txt +4 -0
- snowflake_connector_python-3.16.0.dist-info/licenses/LICENSE.txt +202 -0
- snowflake_connector_python-3.16.0.dist-info/licenses/NOTICE +8 -0
- snowflake_connector_python-3.16.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
from collections import deque
|
|
5
|
+
from concurrent.futures import ALL_COMPLETED, Future, ProcessPoolExecutor, wait
|
|
6
|
+
from concurrent.futures.thread import ThreadPoolExecutor
|
|
7
|
+
from logging import getLogger
|
|
8
|
+
from typing import (
|
|
9
|
+
TYPE_CHECKING,
|
|
10
|
+
Any,
|
|
11
|
+
Callable,
|
|
12
|
+
Deque,
|
|
13
|
+
Iterable,
|
|
14
|
+
Iterator,
|
|
15
|
+
Literal,
|
|
16
|
+
overload,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from .constants import IterUnit
|
|
20
|
+
from .errors import NotSupportedError
|
|
21
|
+
from .options import pandas
|
|
22
|
+
from .options import pyarrow as pa
|
|
23
|
+
from .result_batch import (
|
|
24
|
+
ArrowResultBatch,
|
|
25
|
+
DownloadMetrics,
|
|
26
|
+
JSONResultBatch,
|
|
27
|
+
ResultBatch,
|
|
28
|
+
)
|
|
29
|
+
from .telemetry import TelemetryField
|
|
30
|
+
from .time_util import get_time_millis
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
33
|
+
from pandas import DataFrame
|
|
34
|
+
from pyarrow import Table
|
|
35
|
+
|
|
36
|
+
from snowflake.connector.cursor import SnowflakeCursor
|
|
37
|
+
|
|
38
|
+
logger = getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def result_set_iterator(
|
|
42
|
+
first_batch_iter: Iterator[tuple],
|
|
43
|
+
unconsumed_batches: Deque[Future[Iterator[tuple]]],
|
|
44
|
+
unfetched_batches: Deque[ResultBatch],
|
|
45
|
+
final: Callable[[], None],
|
|
46
|
+
prefetch_thread_num: int,
|
|
47
|
+
use_mp: bool,
|
|
48
|
+
**kw: Any,
|
|
49
|
+
) -> Iterator[dict | Exception] | Iterator[tuple | Exception] | Iterator[Table]:
|
|
50
|
+
"""Creates an iterator over some other iterators.
|
|
51
|
+
|
|
52
|
+
Very similar to itertools.chain but we need some keywords to be propagated to
|
|
53
|
+
``_download`` functions later.
|
|
54
|
+
|
|
55
|
+
We need this to have ResultChunks fall out of usage so that they can be garbage
|
|
56
|
+
collected.
|
|
57
|
+
|
|
58
|
+
Just like ``ResultBatch`` iterator, this might yield an ``Exception`` to allow users
|
|
59
|
+
to continue iterating through the rest of the ``ResultBatch``.
|
|
60
|
+
"""
|
|
61
|
+
is_fetch_all = kw.pop("is_fetch_all", False)
|
|
62
|
+
|
|
63
|
+
if use_mp:
|
|
64
|
+
|
|
65
|
+
def create_pool_executor() -> ProcessPoolExecutor:
|
|
66
|
+
return ProcessPoolExecutor(prefetch_thread_num)
|
|
67
|
+
|
|
68
|
+
def create_fetch_task(batch: ResultBatch):
|
|
69
|
+
return batch.populate_data
|
|
70
|
+
|
|
71
|
+
def get_fetch_result(future_result: ResultBatch):
|
|
72
|
+
return future_result.create_iter(**kw)
|
|
73
|
+
|
|
74
|
+
kw["connection"] = None
|
|
75
|
+
else:
|
|
76
|
+
|
|
77
|
+
def create_pool_executor() -> ThreadPoolExecutor:
|
|
78
|
+
return ThreadPoolExecutor(prefetch_thread_num)
|
|
79
|
+
|
|
80
|
+
def create_fetch_task(batch: ResultBatch):
|
|
81
|
+
return batch.create_iter
|
|
82
|
+
|
|
83
|
+
def get_fetch_result(future_result: Iterator):
|
|
84
|
+
return future_result
|
|
85
|
+
|
|
86
|
+
if is_fetch_all:
|
|
87
|
+
with create_pool_executor() as pool:
|
|
88
|
+
logger.debug("beginning to schedule result batch downloads")
|
|
89
|
+
yield from first_batch_iter
|
|
90
|
+
while unfetched_batches:
|
|
91
|
+
logger.debug(
|
|
92
|
+
f"queuing download of result batch id: {unfetched_batches[0].id}"
|
|
93
|
+
)
|
|
94
|
+
future = pool.submit(
|
|
95
|
+
create_fetch_task(unfetched_batches.popleft()), **kw
|
|
96
|
+
)
|
|
97
|
+
unconsumed_batches.append(future)
|
|
98
|
+
_, _ = wait(unconsumed_batches, return_when=ALL_COMPLETED)
|
|
99
|
+
i = 1
|
|
100
|
+
while unconsumed_batches:
|
|
101
|
+
logger.debug(f"user began consuming result batch {i}")
|
|
102
|
+
yield from get_fetch_result(unconsumed_batches.popleft().result())
|
|
103
|
+
logger.debug(f"user began consuming result batch {i}")
|
|
104
|
+
i += 1
|
|
105
|
+
final()
|
|
106
|
+
else:
|
|
107
|
+
with create_pool_executor() as pool:
|
|
108
|
+
# Fill up window
|
|
109
|
+
|
|
110
|
+
logger.debug("beginning to schedule result batch downloads")
|
|
111
|
+
|
|
112
|
+
for _ in range(min(prefetch_thread_num, len(unfetched_batches))):
|
|
113
|
+
logger.debug(
|
|
114
|
+
f"queuing download of result batch id: {unfetched_batches[0].id}"
|
|
115
|
+
)
|
|
116
|
+
unconsumed_batches.append(
|
|
117
|
+
pool.submit(create_fetch_task(unfetched_batches.popleft()), **kw)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
yield from first_batch_iter
|
|
121
|
+
|
|
122
|
+
i = 1
|
|
123
|
+
while unconsumed_batches:
|
|
124
|
+
logger.debug(f"user requesting to consume result batch {i}")
|
|
125
|
+
|
|
126
|
+
# Submit the next un-fetched batch to the pool
|
|
127
|
+
if unfetched_batches:
|
|
128
|
+
logger.debug(
|
|
129
|
+
f"queuing download of result batch id: {unfetched_batches[0].id}"
|
|
130
|
+
)
|
|
131
|
+
future = pool.submit(
|
|
132
|
+
create_fetch_task(unfetched_batches.popleft()), **kw
|
|
133
|
+
)
|
|
134
|
+
unconsumed_batches.append(future)
|
|
135
|
+
|
|
136
|
+
future = unconsumed_batches.popleft()
|
|
137
|
+
|
|
138
|
+
# this will raise an exception if one has occurred
|
|
139
|
+
batch_iterator = get_fetch_result(future.result())
|
|
140
|
+
|
|
141
|
+
logger.debug(f"user began consuming result batch {i}")
|
|
142
|
+
yield from batch_iterator
|
|
143
|
+
logger.debug(f"user finished consuming result batch {i}")
|
|
144
|
+
|
|
145
|
+
i += 1
|
|
146
|
+
final()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class ResultSet(Iterable[list]):
|
|
150
|
+
"""This class retrieves the results of a query with the historical strategy.
|
|
151
|
+
|
|
152
|
+
It pre-downloads the first up to 4 ResultChunks (this doesn't include the 1st chunk
|
|
153
|
+
as that is embedded in the response JSON from Snowflake) upon creating an Iterator
|
|
154
|
+
on it.
|
|
155
|
+
|
|
156
|
+
It also reports telemetry data about its ``ResultBatch``es once it's done iterating
|
|
157
|
+
through them.
|
|
158
|
+
|
|
159
|
+
Currently we do not support mixing multiple ``ResultBatch`` types and having
|
|
160
|
+
different column definitions types per ``ResultBatch``.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def __init__(
|
|
164
|
+
self,
|
|
165
|
+
cursor: SnowflakeCursor,
|
|
166
|
+
result_chunks: list[JSONResultBatch] | list[ArrowResultBatch],
|
|
167
|
+
prefetch_thread_num: int,
|
|
168
|
+
use_mp: bool,
|
|
169
|
+
) -> None:
|
|
170
|
+
self.batches = result_chunks
|
|
171
|
+
self._cursor = cursor
|
|
172
|
+
self.prefetch_thread_num = prefetch_thread_num
|
|
173
|
+
self._use_mp = use_mp
|
|
174
|
+
|
|
175
|
+
def _report_metrics(self) -> None:
|
|
176
|
+
"""Report all metrics totalled up.
|
|
177
|
+
|
|
178
|
+
This includes TIME_CONSUME_LAST_RESULT, TIME_DOWNLOADING_CHUNKS and
|
|
179
|
+
TIME_PARSING_CHUNKS in that order.
|
|
180
|
+
"""
|
|
181
|
+
if self._cursor._first_chunk_time is not None:
|
|
182
|
+
time_consume_last_result = (
|
|
183
|
+
get_time_millis() - self._cursor._first_chunk_time
|
|
184
|
+
)
|
|
185
|
+
self._cursor._log_telemetry_job_data(
|
|
186
|
+
TelemetryField.TIME_CONSUME_LAST_RESULT, time_consume_last_result
|
|
187
|
+
)
|
|
188
|
+
metrics = self._get_metrics()
|
|
189
|
+
if DownloadMetrics.download.value in metrics:
|
|
190
|
+
self._cursor._log_telemetry_job_data(
|
|
191
|
+
TelemetryField.TIME_DOWNLOADING_CHUNKS,
|
|
192
|
+
metrics.get(DownloadMetrics.download.value),
|
|
193
|
+
)
|
|
194
|
+
if DownloadMetrics.parse.value in metrics:
|
|
195
|
+
self._cursor._log_telemetry_job_data(
|
|
196
|
+
TelemetryField.TIME_PARSING_CHUNKS,
|
|
197
|
+
metrics.get(DownloadMetrics.parse.value),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
def _finish_iterating(self) -> None:
|
|
201
|
+
"""Used for any cleanup after the result set iterator is done."""
|
|
202
|
+
|
|
203
|
+
self._report_metrics()
|
|
204
|
+
|
|
205
|
+
def _can_create_arrow_iter(self) -> None:
|
|
206
|
+
# For now we don't support mixed ResultSets, so assume first partition's type
|
|
207
|
+
# represents them all
|
|
208
|
+
head_type = type(self.batches[0])
|
|
209
|
+
if head_type != ArrowResultBatch:
|
|
210
|
+
raise NotSupportedError(
|
|
211
|
+
f"Trying to use arrow fetching on {head_type} which "
|
|
212
|
+
f"is not ArrowResultChunk"
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
def _fetch_arrow_batches(
|
|
216
|
+
self,
|
|
217
|
+
) -> Iterator[Table]:
|
|
218
|
+
"""Fetches all the results as Arrow Tables, chunked by Snowflake back-end."""
|
|
219
|
+
self._can_create_arrow_iter()
|
|
220
|
+
return self._create_iter(iter_unit=IterUnit.TABLE_UNIT, structure="arrow")
|
|
221
|
+
|
|
222
|
+
@overload
|
|
223
|
+
def _fetch_arrow_all(self, force_return_table: Literal[False]) -> Table | None: ...
|
|
224
|
+
|
|
225
|
+
@overload
|
|
226
|
+
def _fetch_arrow_all(self, force_return_table: Literal[True]) -> Table: ...
|
|
227
|
+
|
|
228
|
+
def _fetch_arrow_all(self, force_return_table: bool = False) -> Table | None:
|
|
229
|
+
"""Fetches a single Arrow Table from all of the ``ResultBatch``."""
|
|
230
|
+
tables = list(self._fetch_arrow_batches())
|
|
231
|
+
if tables:
|
|
232
|
+
return pa.concat_tables(tables)
|
|
233
|
+
else:
|
|
234
|
+
return self.batches[0].to_arrow() if force_return_table else None
|
|
235
|
+
|
|
236
|
+
def _fetch_pandas_batches(self, **kwargs) -> Iterator[DataFrame]:
|
|
237
|
+
"""Fetches Pandas dataframes in batches, where batch refers to Snowflake Chunk.
|
|
238
|
+
|
|
239
|
+
Thus, the batch size (the number of rows in dataframe) is determined by
|
|
240
|
+
Snowflake's back-end.
|
|
241
|
+
"""
|
|
242
|
+
self._can_create_arrow_iter()
|
|
243
|
+
return self._create_iter(
|
|
244
|
+
iter_unit=IterUnit.TABLE_UNIT, structure="pandas", **kwargs
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
def _fetch_pandas_all(self, **kwargs) -> DataFrame:
|
|
248
|
+
"""Fetches a single Pandas dataframe."""
|
|
249
|
+
concat_args = list(inspect.signature(pandas.concat).parameters)
|
|
250
|
+
concat_kwargs = {k: kwargs.pop(k) for k in dict(kwargs) if k in concat_args}
|
|
251
|
+
dataframes = list(self._fetch_pandas_batches(is_fetch_all=True, **kwargs))
|
|
252
|
+
if dataframes:
|
|
253
|
+
return pandas.concat(
|
|
254
|
+
dataframes,
|
|
255
|
+
ignore_index=True, # Don't keep in result batch indexes
|
|
256
|
+
**concat_kwargs,
|
|
257
|
+
)
|
|
258
|
+
# Empty dataframe
|
|
259
|
+
return self.batches[0].to_pandas(**kwargs)
|
|
260
|
+
|
|
261
|
+
def _get_metrics(self) -> dict[str, int]:
|
|
262
|
+
"""Sum up all the chunks' metrics and show them together."""
|
|
263
|
+
overall_metrics: dict[str, int] = {}
|
|
264
|
+
for c in self.batches:
|
|
265
|
+
for n, v in c._metrics.items():
|
|
266
|
+
overall_metrics[n] = overall_metrics.get(n, 0) + v
|
|
267
|
+
return overall_metrics
|
|
268
|
+
|
|
269
|
+
def __iter__(self) -> Iterator[tuple]:
|
|
270
|
+
"""Returns a new iterator through all batches with default values."""
|
|
271
|
+
return self._create_iter()
|
|
272
|
+
|
|
273
|
+
def _create_iter(
|
|
274
|
+
self,
|
|
275
|
+
**kwargs,
|
|
276
|
+
) -> (
|
|
277
|
+
Iterator[dict | Exception]
|
|
278
|
+
| Iterator[tuple | Exception]
|
|
279
|
+
| Iterator[Table]
|
|
280
|
+
| Iterator[DataFrame]
|
|
281
|
+
):
|
|
282
|
+
"""Set up a new iterator through all batches with first 5 chunks downloaded.
|
|
283
|
+
|
|
284
|
+
This function is a helper function to ``__iter__`` and it was introduced for the
|
|
285
|
+
cases where we need to propagate some values to later ``_download`` calls.
|
|
286
|
+
"""
|
|
287
|
+
# pop is_fetch_all and pass it to result_set_iterator
|
|
288
|
+
is_fetch_all = kwargs.pop("is_fetch_all", False)
|
|
289
|
+
|
|
290
|
+
# add connection so that result batches can use sessions
|
|
291
|
+
kwargs["connection"] = self._cursor.connection
|
|
292
|
+
|
|
293
|
+
first_batch_iter = self.batches[0].create_iter(**kwargs)
|
|
294
|
+
|
|
295
|
+
# Iterator[Tuple] Futures that have not been consumed by the user
|
|
296
|
+
unconsumed_batches: Deque[Future[Iterator[tuple]]] = deque()
|
|
297
|
+
|
|
298
|
+
# batches that have not been fetched
|
|
299
|
+
unfetched_batches = deque(self.batches[1:])
|
|
300
|
+
for num, batch in enumerate(unfetched_batches):
|
|
301
|
+
logger.debug(f"result batch {num + 1} has id: {batch.id}")
|
|
302
|
+
|
|
303
|
+
return result_set_iterator(
|
|
304
|
+
first_batch_iter,
|
|
305
|
+
unconsumed_batches,
|
|
306
|
+
unfetched_batches,
|
|
307
|
+
self._finish_iterating,
|
|
308
|
+
self.prefetch_thread_num,
|
|
309
|
+
is_fetch_all=is_fetch_all,
|
|
310
|
+
use_mp=self._use_mp,
|
|
311
|
+
**kwargs,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
def total_row_index(self) -> int:
|
|
315
|
+
"""Returns the total rowcount of the ``ResultSet`` ."""
|
|
316
|
+
total = 0
|
|
317
|
+
for p in self.batches:
|
|
318
|
+
total += p.rowcount
|
|
319
|
+
return total
|