snowflake-connector-python 5.2.0__cp315-cp315-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 +148 -0
- snowflake/connector/_common/__init__.py +0 -0
- snowflake/connector/_common/extras.py +134 -0
- snowflake/connector/_common/telemetry.py +221 -0
- snowflake/connector/_common/wif_util.py +92 -0
- snowflake/connector/_core/sf_core_python.cp315-win_amd64.pyd +0 -0
- snowflake/connector/_core/sf_core_python.pyi +79 -0
- snowflake/connector/_internal/__init__.py +6 -0
- snowflake/connector/_internal/_private_key_helper.py +31 -0
- snowflake/connector/_internal/api_client/__init__.py +93 -0
- snowflake/connector/_internal/api_client/bridge.py +41 -0
- snowflake/connector/_internal/api_client/client_api.py +976 -0
- snowflake/connector/_internal/arrow.py +47 -0
- snowflake/connector/_internal/arrow_context.py +240 -0
- snowflake/connector/_internal/arrow_stream_async.py +266 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp311-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp312-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp313-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp314-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp314t-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.cp315-win_amd64.pyd +0 -0
- snowflake/connector/_internal/arrow_stream_iterator.pyi +42 -0
- snowflake/connector/_internal/arrow_stream_utils.py +171 -0
- snowflake/connector/_internal/authenticator_type.py +53 -0
- snowflake/connector/_internal/backward_compatibility.py +245 -0
- snowflake/connector/_internal/binding_converters.py +741 -0
- snowflake/connector/_internal/config_utils.py +71 -0
- snowflake/connector/_internal/connection/__init__.py +39 -0
- snowflake/connector/_internal/connection/connection.py +616 -0
- snowflake/connector/_internal/connection/connection_types.py +13 -0
- snowflake/connector/_internal/connection/constants.py +25 -0
- snowflake/connector/_internal/connection/decorators.py +31 -0
- snowflake/connector/_internal/connection/freezable_proxy.py +104 -0
- snowflake/connector/_internal/connection/queries.py +10 -0
- snowflake/connector/_internal/connection_config_mixin.py +755 -0
- snowflake/connector/_internal/cursor/__init__.py +25 -0
- snowflake/connector/_internal/cursor/base.py +732 -0
- snowflake/connector/_internal/cursor/cursor_types.py +13 -0
- snowflake/connector/_internal/cursor/decorators.py +56 -0
- snowflake/connector/_internal/cursor/query_result.py +202 -0
- snowflake/connector/_internal/cursor/query_result_waiter.py +98 -0
- snowflake/connector/_internal/cursor/result_metadata.py +255 -0
- snowflake/connector/_internal/cursor/result_set_wrapper.py +66 -0
- snowflake/connector/_internal/decorators.py +539 -0
- snowflake/connector/_internal/error_kinds.py +111 -0
- snowflake/connector/_internal/errorcode.py +35 -0
- snowflake/connector/_internal/errorhandler.py +278 -0
- snowflake/connector/_internal/fips.py +28 -0
- snowflake/connector/_internal/logging/__init__.py +52 -0
- snowflake/connector/_internal/logging/config.py +134 -0
- snowflake/connector/_internal/logging/core_logger.py +218 -0
- snowflake/connector/_internal/logging/native_extension_logger.py +144 -0
- snowflake/connector/_internal/logout_config_mapping.py +187 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.cpp +57 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrayConverter.hpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.cpp +943 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ArrowTableConverter.hpp +63 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.cpp +18 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BinaryConverter.hpp +26 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.cpp +21 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/BooleanConverter.hpp +23 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.cpp +118 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowIterator.hpp +116 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.cpp +323 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamIterator.hpp +133 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.cpp +275 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/CArrowStreamTableIterator.hpp +168 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.cpp +439 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ConverterUtil.hpp +30 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.cpp +48 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DateConverter.hpp +46 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.cpp +76 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecFloatConverter.hpp +35 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.cpp +90 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/DecimalConverter.hpp +63 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.cpp +62 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FixedSizeListConverter.hpp +28 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.cpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/FloatConverter.hpp +35 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IColumnConverter.hpp +17 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.cpp +23 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntConverter.hpp +41 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.cpp +65 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/IntervalConverter.hpp +54 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/LICENSE.txt +209 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.cpp +79 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/MapConverter.hpp +30 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.cpp +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/ObjectConverter.hpp +29 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.cpp +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Common.hpp +117 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.cpp +54 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Python/Helpers.hpp +34 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.cpp +33 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/SnowflakeType.hpp +48 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.cpp +18 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/StringConverter.hpp +26 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.cpp +39 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeConverter.hpp +31 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.cpp +326 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/TimeStampConverter.hpp +138 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/macros.hpp +14 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.cpp +65 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/Util/time.hpp +68 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.cpp +13278 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/arrow_stream_iterator.pyx +204 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_accessors.h +109 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_alloc.h +125 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_assert.h +45 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_builder.h +1914 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_emitter.h +208 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_endian.h +128 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_epilogue.h +7 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_flatbuffers.h +58 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_identifier.h +144 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_iov.h +31 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_prologue.h +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_refmap.h +144 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_rtconfig.h +160 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_types.h +98 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/flatcc_verifier.h +243 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/flatcc_portable.h +14 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/paligned_alloc.h +207 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pattributes.h +80 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic.h +83 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_pop.h +20 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pdiagnostic_push.h +51 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian.h +201 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pendian_detect.h +108 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinline.h +19 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pinttypes.h +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable.h +2 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/portable_basic.h +25 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstatic_assert.h +67 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdalign.h +164 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pstdint.h +926 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/punaligned.h +182 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pversion.h +6 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc/portable/pwarnings.h +52 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/flatcc.c +3052 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.c +3019 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.h +3354 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow.hpp +344 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.c +29305 -0
- snowflake/connector/_internal/nanoarrow_cpp/ArrowIterator/nanoarrow_ipc.h +381 -0
- snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.cpp +108 -0
- snowflake/connector/_internal/nanoarrow_cpp/Logging/logging.hpp +47 -0
- snowflake/connector/_internal/nanoarrow_cpp/scripts/.clang-format +8 -0
- snowflake/connector/_internal/nanoarrow_cpp/scripts/format.sh +8 -0
- snowflake/connector/_internal/protobuf_gen/__init__.py +0 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.py +408 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_pb2.pyi +4487 -0
- snowflake/connector/_internal/protobuf_gen/database_driver_v1_services.py +2088 -0
- snowflake/connector/_internal/protobuf_gen/proto_exception.py +17 -0
- snowflake/connector/_internal/result_batch.py +150 -0
- snowflake/connector/_internal/snowflake_restful.py +222 -0
- snowflake/connector/_internal/snowpark_backcompat_helpers.py +31 -0
- snowflake/connector/_internal/sqlstate.py +11 -0
- snowflake/connector/_internal/statement_utils.py +207 -0
- snowflake/connector/_internal/text_utils.py +112 -0
- snowflake/connector/_internal/type_codes.py +139 -0
- snowflake/connector/_internal/utils.py +65 -0
- snowflake/connector/_internal/write_pandas_operation.py +657 -0
- snowflake/connector/aio/README.md +168 -0
- snowflake/connector/aio/__init__.py +37 -0
- snowflake/connector/aio/connection/__init__.py +17 -0
- snowflake/connector/aio/connection/_connection.py +506 -0
- snowflake/connector/aio/cursor/__init__.py +35 -0
- snowflake/connector/aio/cursor/_base.py +1034 -0
- snowflake/connector/aio/cursor/_dict_cursor.py +78 -0
- snowflake/connector/aio/cursor/_result_set_wrapper.py +35 -0
- snowflake/connector/aio/cursor/_snowflake_cursor.py +72 -0
- snowflake/connector/aio/pandas_tools.py +279 -0
- snowflake/connector/aio/result_batch.py +165 -0
- snowflake/connector/auth/__init__.py +0 -0
- snowflake/connector/auth/workload_identity.py +5 -0
- snowflake/connector/compat.py +22 -0
- snowflake/connector/config_manager.py +392 -0
- snowflake/connector/connection/__init__.py +30 -0
- snowflake/connector/connection/_connection.py +641 -0
- snowflake/connector/connection_config.py +517 -0
- snowflake/connector/constants.py +52 -0
- snowflake/connector/cursor/__init__.py +37 -0
- snowflake/connector/cursor/_base.py +1169 -0
- snowflake/connector/cursor/_chunked_download_reader.py +75 -0
- snowflake/connector/cursor/_dict_cursor.py +78 -0
- snowflake/connector/cursor/_result_set_wrapper.py +35 -0
- snowflake/connector/cursor/_snowflake_cursor.py +72 -0
- snowflake/connector/description.py +7 -0
- snowflake/connector/errors.py +492 -0
- snowflake/connector/network.py +71 -0
- snowflake/connector/pandas_tools.py +191 -0
- snowflake/connector/py.typed +0 -0
- snowflake/connector/result_batch.py +216 -0
- snowflake/connector/telemetry.py +40 -0
- snowflake/connector/time_util.py +11 -0
- snowflake/connector/types.py +134 -0
- snowflake/connector/util_text.py +3 -0
- snowflake/connector/version.py +23 -0
- snowflake_connector_python-5.2.0.dist-info/DELVEWHEEL +2 -0
- snowflake_connector_python-5.2.0.dist-info/METADATA +190 -0
- snowflake_connector_python-5.2.0.dist-info/RECORD +204 -0
- snowflake_connector_python-5.2.0.dist-info/WHEEL +4 -0
- snowflake_connector_python.libs/msvcp140-a4c2229bdc2a2a630acdc095b4d86008.dll +0 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
"""Async PEP 249 Connection implementation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import os
|
|
7
|
+
import platform
|
|
8
|
+
import warnings
|
|
9
|
+
|
|
10
|
+
from collections.abc import AsyncGenerator, Callable, Iterable, Iterator
|
|
11
|
+
from io import StringIO
|
|
12
|
+
from typing import Any, TypeVar, overload
|
|
13
|
+
|
|
14
|
+
from ..._common.telemetry import AsyncTelemetryClient
|
|
15
|
+
from ..._internal.api_client.client_api import async_core_driver, core_driver
|
|
16
|
+
from ..._internal.config_utils import create_config_settings_from_dict
|
|
17
|
+
from ..._internal.connection import (
|
|
18
|
+
APPLICATION_NAME,
|
|
19
|
+
COMMIT_SQL,
|
|
20
|
+
CURRENT_VERSION_SQL,
|
|
21
|
+
ROLLBACK_SQL,
|
|
22
|
+
SET_AUTOCOMMIT_SQL,
|
|
23
|
+
SET_CLIENT_PREFETCH_THREADS_SQL,
|
|
24
|
+
ConnectionMixin,
|
|
25
|
+
clamp_client_prefetch_threads,
|
|
26
|
+
requires_open,
|
|
27
|
+
validate_query_id,
|
|
28
|
+
)
|
|
29
|
+
from ..._internal.connection.freezable_proxy import ConnectionInfoProxy as _ConnectionInfoProxy
|
|
30
|
+
from ..._internal.connection.freezable_proxy import SessionParametersProxy as _SessionParametersProxy
|
|
31
|
+
from ..._internal.decorators import (
|
|
32
|
+
api_telemetry,
|
|
33
|
+
backward_compatibility,
|
|
34
|
+
internal_api,
|
|
35
|
+
pep249,
|
|
36
|
+
)
|
|
37
|
+
from ..._internal.errorcode import ER_INVALID_VALUE, ER_INVALID_WIF_SETTINGS
|
|
38
|
+
from ..._internal.logging import get_logger
|
|
39
|
+
from ..._internal.logout_config_mapping import (
|
|
40
|
+
LogoutOptionKeys,
|
|
41
|
+
logout_config_options_modifier,
|
|
42
|
+
)
|
|
43
|
+
from ..._internal.protobuf_gen.database_driver_v1_pb2 import (
|
|
44
|
+
VALIDATION_CODE_CONFLICTING_WIF_PARAMETERS,
|
|
45
|
+
ConnectionGetQueryStatusResponse,
|
|
46
|
+
ConnectionHandle,
|
|
47
|
+
DatabaseHandle,
|
|
48
|
+
WrapperIdentity,
|
|
49
|
+
)
|
|
50
|
+
from ..._internal.text_utils import split_statements
|
|
51
|
+
from ..._internal.utils import get_application_path
|
|
52
|
+
from ...connection_config import ConnectionConfig
|
|
53
|
+
from ...constants import QueryStatus
|
|
54
|
+
from ...errors import Error, ProgrammingError
|
|
55
|
+
from ...version import __version__
|
|
56
|
+
from ..cursor import CursorInstance, CursorType, DictCursor, SnowflakeCursor, SnowflakeCursorBase
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
logger = get_logger(__name__)
|
|
60
|
+
|
|
61
|
+
_CursorClsT = TypeVar("_CursorClsT", bound=SnowflakeCursorBase)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Both WIF cross-param guards in sf_core's validate_settings emit a dedicated
|
|
65
|
+
# ValidationCode, so the wrapper can key on the code alone without matching
|
|
66
|
+
# parameter names or message text.
|
|
67
|
+
def _is_wif_conflict(exc: ProgrammingError) -> bool:
|
|
68
|
+
return exc.validation_code == VALIDATION_CODE_CONFLICTING_WIF_PARAMETERS
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
_CALLBACK_EXHAUSTED = object()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _next_or_exhausted(iterator: Iterator[None]) -> object:
|
|
75
|
+
return next(iterator, _CALLBACK_EXHAUSTED)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class Connection(ConnectionMixin):
|
|
79
|
+
"""Async connection objects represent a database connection."""
|
|
80
|
+
|
|
81
|
+
_session_parameters: _SessionParametersProxy
|
|
82
|
+
_connection_info: _ConnectionInfoProxy
|
|
83
|
+
_default_cursor_class = SnowflakeCursor
|
|
84
|
+
|
|
85
|
+
# ------------------------------------------------------------------
|
|
86
|
+
# Initialization
|
|
87
|
+
# ------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
@api_telemetry
|
|
90
|
+
def __init__(
|
|
91
|
+
self,
|
|
92
|
+
*,
|
|
93
|
+
connection_name: str | None = None,
|
|
94
|
+
connections_file_path: str | os.PathLike[str] | None = None,
|
|
95
|
+
config: ConnectionConfig | None = None,
|
|
96
|
+
**kwargs: Any,
|
|
97
|
+
) -> None:
|
|
98
|
+
"""
|
|
99
|
+
Initialize configuration for a new async connection object.
|
|
100
|
+
|
|
101
|
+
Unlike :class:`~snowflake.connector.connection.Connection`, this does not
|
|
102
|
+
perform any I/O. Call :meth:`connect`, use
|
|
103
|
+
:func:`~snowflake.connector.aio.connect`, or ``async with`` to
|
|
104
|
+
establish the session.
|
|
105
|
+
"""
|
|
106
|
+
super().__init__(
|
|
107
|
+
connection_name=connection_name,
|
|
108
|
+
connections_file_path=connections_file_path,
|
|
109
|
+
config=config,
|
|
110
|
+
**kwargs,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
self.db_handle: DatabaseHandle | None = None
|
|
114
|
+
self.conn_handle: ConnectionHandle | None = None
|
|
115
|
+
self._ever_opened = False
|
|
116
|
+
self._close_lock = asyncio.Lock()
|
|
117
|
+
self._session_parameters = _SessionParametersProxy(None)
|
|
118
|
+
self._connection_info = _ConnectionInfoProxy(None)
|
|
119
|
+
self._telemetry_client: AsyncTelemetryClient | None = None
|
|
120
|
+
|
|
121
|
+
# ------------------------------------------------------------------
|
|
122
|
+
# Connection setup
|
|
123
|
+
# ------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
@api_telemetry
|
|
126
|
+
async def connect(self) -> None:
|
|
127
|
+
"""Establish the connection to Snowflake via the Rust core."""
|
|
128
|
+
if self.conn_handle is not None:
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
db_handle = (await async_core_driver.database_new()).db_handle
|
|
132
|
+
await async_core_driver.database_init(db_handle=db_handle)
|
|
133
|
+
conn_handle = (await async_core_driver.connection_new()).conn_handle
|
|
134
|
+
|
|
135
|
+
options = self.config.to_proto_options(
|
|
136
|
+
options_modifiers=[logout_config_options_modifier],
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if options:
|
|
140
|
+
response = await async_core_driver.connection_set_options(
|
|
141
|
+
conn_handle=conn_handle,
|
|
142
|
+
options=options,
|
|
143
|
+
no_connection_details=self.config._no_connection_details,
|
|
144
|
+
connections_file_path=self.config.connections_file_path,
|
|
145
|
+
)
|
|
146
|
+
for warning in response.warnings:
|
|
147
|
+
warnings.warn(warning.message, stacklevel=2)
|
|
148
|
+
|
|
149
|
+
session_params = self.config.session_parameters
|
|
150
|
+
if session_params:
|
|
151
|
+
await async_core_driver.connection_set_session_parameters(
|
|
152
|
+
conn_handle=conn_handle,
|
|
153
|
+
parameters=session_params,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
try:
|
|
157
|
+
if self.config.mfa_callback is None:
|
|
158
|
+
await self._initialize_core_connection(conn_handle, db_handle)
|
|
159
|
+
else:
|
|
160
|
+
await self._initialize_core_connection_with_mfa_callback(
|
|
161
|
+
conn_handle, db_handle, self.config.mfa_callback
|
|
162
|
+
)
|
|
163
|
+
except ProgrammingError as e:
|
|
164
|
+
# The WIF cross-param guards fire in sf_core only via connection_init
|
|
165
|
+
# (ConnectionConfig::build -> validate_settings), surfaced as errno
|
|
166
|
+
# ER_INVALID_VALUE. Re-map to ER_INVALID_WIF_SETTINGS for legacy parity.
|
|
167
|
+
if _is_wif_conflict(e):
|
|
168
|
+
raise ProgrammingError(
|
|
169
|
+
msg=str(e),
|
|
170
|
+
errno=ER_INVALID_WIF_SETTINGS,
|
|
171
|
+
parameter=e.parameter,
|
|
172
|
+
validation_code=e.validation_code,
|
|
173
|
+
) from e
|
|
174
|
+
raise
|
|
175
|
+
|
|
176
|
+
self.conn_handle = conn_handle
|
|
177
|
+
self.db_handle = db_handle
|
|
178
|
+
self._ever_opened = True
|
|
179
|
+
self._session_parameters = _SessionParametersProxy(conn_handle)
|
|
180
|
+
self._connection_info = _ConnectionInfoProxy(conn_handle)
|
|
181
|
+
self._telemetry_client = AsyncTelemetryClient(conn_handle)
|
|
182
|
+
|
|
183
|
+
async def _initialize_core_connection(self, conn_handle: ConnectionHandle, db_handle: DatabaseHandle) -> None:
|
|
184
|
+
await async_core_driver.connection_init(
|
|
185
|
+
conn_handle=conn_handle,
|
|
186
|
+
db_handle=db_handle,
|
|
187
|
+
wrapper_identity=WrapperIdentity(
|
|
188
|
+
driver_name=APPLICATION_NAME,
|
|
189
|
+
driver_version=__version__,
|
|
190
|
+
language_runtime=platform.python_implementation(),
|
|
191
|
+
language_version=platform.python_version(),
|
|
192
|
+
language_compiler=platform.python_compiler(),
|
|
193
|
+
application_path=get_application_path(),
|
|
194
|
+
),
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
async def _initialize_core_connection_with_mfa_callback(
|
|
198
|
+
self,
|
|
199
|
+
conn_handle: ConnectionHandle,
|
|
200
|
+
db_handle: DatabaseHandle,
|
|
201
|
+
mfa_callback: Callable[[], Iterator[None]],
|
|
202
|
+
) -> None:
|
|
203
|
+
callback = mfa_callback()
|
|
204
|
+
init_task = asyncio.create_task(self._initialize_core_connection(conn_handle, db_handle))
|
|
205
|
+
try:
|
|
206
|
+
while not init_task.done():
|
|
207
|
+
item = await asyncio.to_thread(_next_or_exhausted, callback)
|
|
208
|
+
if item is _CALLBACK_EXHAUSTED:
|
|
209
|
+
break
|
|
210
|
+
finally:
|
|
211
|
+
await init_task
|
|
212
|
+
|
|
213
|
+
# ------------------------------------------------------------------
|
|
214
|
+
# Lifecycle
|
|
215
|
+
# ------------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
@pep249
|
|
218
|
+
@api_telemetry
|
|
219
|
+
async def close(self, retry: bool = True) -> None:
|
|
220
|
+
"""Close the connection, send logout, and release handles."""
|
|
221
|
+
if self.conn_handle is None or self.is_closed():
|
|
222
|
+
self._close_telemetry_client()
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
session_parameters = self._session_parameters
|
|
226
|
+
connection_info = self._connection_info
|
|
227
|
+
session_parameters.freeze()
|
|
228
|
+
connection_info.freeze()
|
|
229
|
+
|
|
230
|
+
async with self._close_lock:
|
|
231
|
+
del self._messages[:]
|
|
232
|
+
conn_handle, self.conn_handle = self.conn_handle, None
|
|
233
|
+
db_handle, self.db_handle = self.db_handle, None
|
|
234
|
+
self._close_telemetry_client()
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
if conn_handle and not retry:
|
|
238
|
+
await async_core_driver.connection_set_options(
|
|
239
|
+
conn_handle=conn_handle,
|
|
240
|
+
options=create_config_settings_from_dict({LogoutOptionKeys.LOGOUT_MAX_ATTEMPTS: 1}),
|
|
241
|
+
)
|
|
242
|
+
if conn_handle:
|
|
243
|
+
await async_core_driver.connection_close(conn_handle=conn_handle)
|
|
244
|
+
finally:
|
|
245
|
+
if conn_handle:
|
|
246
|
+
self._release_connection_handle(conn_handle)
|
|
247
|
+
if db_handle:
|
|
248
|
+
self._release_database_handle(db_handle)
|
|
249
|
+
|
|
250
|
+
# ------------------------------------------------------------------
|
|
251
|
+
# Transactions
|
|
252
|
+
# ------------------------------------------------------------------
|
|
253
|
+
|
|
254
|
+
@pep249
|
|
255
|
+
@api_telemetry
|
|
256
|
+
@requires_open
|
|
257
|
+
async def commit(self) -> None:
|
|
258
|
+
cur = self.cursor()
|
|
259
|
+
try:
|
|
260
|
+
await cur.execute(COMMIT_SQL)
|
|
261
|
+
finally:
|
|
262
|
+
cur.close()
|
|
263
|
+
|
|
264
|
+
@pep249
|
|
265
|
+
@api_telemetry
|
|
266
|
+
@requires_open
|
|
267
|
+
async def rollback(self) -> None:
|
|
268
|
+
cur = self.cursor()
|
|
269
|
+
try:
|
|
270
|
+
await cur.execute(ROLLBACK_SQL)
|
|
271
|
+
finally:
|
|
272
|
+
cur.close()
|
|
273
|
+
|
|
274
|
+
# ------------------------------------------------------------------
|
|
275
|
+
# Context manager
|
|
276
|
+
# ------------------------------------------------------------------
|
|
277
|
+
|
|
278
|
+
async def __aenter__(self) -> Connection:
|
|
279
|
+
await self.connect()
|
|
280
|
+
return self
|
|
281
|
+
|
|
282
|
+
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
283
|
+
try:
|
|
284
|
+
if not self.is_closed() and not self._autocommit_enabled():
|
|
285
|
+
if exc_type is None:
|
|
286
|
+
await self.commit()
|
|
287
|
+
else:
|
|
288
|
+
try:
|
|
289
|
+
await self.rollback()
|
|
290
|
+
except Exception:
|
|
291
|
+
logger.warning("Rollback failed during exception handling", exc_info=True)
|
|
292
|
+
finally:
|
|
293
|
+
await self.close()
|
|
294
|
+
|
|
295
|
+
# ------------------------------------------------------------------
|
|
296
|
+
# Autocommit
|
|
297
|
+
# ------------------------------------------------------------------
|
|
298
|
+
|
|
299
|
+
@requires_open
|
|
300
|
+
@api_telemetry
|
|
301
|
+
async def set_autocommit(self, autocommit: bool) -> None:
|
|
302
|
+
if not isinstance(autocommit, bool):
|
|
303
|
+
raise ProgrammingError(msg=f"Invalid autocommit parameter: {autocommit!r}", errno=ER_INVALID_VALUE)
|
|
304
|
+
cur = self.cursor()
|
|
305
|
+
try:
|
|
306
|
+
await cur.execute(SET_AUTOCOMMIT_SQL.format(autocommit=str(autocommit).lower()))
|
|
307
|
+
except Error as e:
|
|
308
|
+
logger.warning("Autocommit feature is not enabled for this connection. Ignored: %s", e)
|
|
309
|
+
finally:
|
|
310
|
+
cur.close()
|
|
311
|
+
|
|
312
|
+
@pep249
|
|
313
|
+
@api_telemetry
|
|
314
|
+
async def autocommit(self, value: bool) -> None:
|
|
315
|
+
await self.set_autocommit(value)
|
|
316
|
+
|
|
317
|
+
# ------------------------------------------------------------------
|
|
318
|
+
# Client prefetch threads
|
|
319
|
+
# ------------------------------------------------------------------
|
|
320
|
+
|
|
321
|
+
@requires_open
|
|
322
|
+
@api_telemetry
|
|
323
|
+
async def set_client_prefetch_threads(self, value: int) -> None:
|
|
324
|
+
"""Set the number of concurrent chunk-prefetch threads.
|
|
325
|
+
|
|
326
|
+
Executes ``ALTER SESSION SET CLIENT_PREFETCH_THREADS`` so the change
|
|
327
|
+
takes effect on subsequent result-set fetches. The inherited
|
|
328
|
+
``client_prefetch_threads`` property setter cannot do this itself —
|
|
329
|
+
a synchronous property setter can't ``await`` — so call this method
|
|
330
|
+
directly for the same immediate effect the legacy connector's setter
|
|
331
|
+
has.
|
|
332
|
+
"""
|
|
333
|
+
value = clamp_client_prefetch_threads(value)
|
|
334
|
+
self.config.client_prefetch_threads = value
|
|
335
|
+
cur = self.cursor()
|
|
336
|
+
try:
|
|
337
|
+
await cur.execute(SET_CLIENT_PREFETCH_THREADS_SQL.format(value=value))
|
|
338
|
+
finally:
|
|
339
|
+
cur.close()
|
|
340
|
+
|
|
341
|
+
# ------------------------------------------------------------------
|
|
342
|
+
# Connection state
|
|
343
|
+
# ------------------------------------------------------------------
|
|
344
|
+
|
|
345
|
+
@api_telemetry
|
|
346
|
+
def is_closed(self) -> bool:
|
|
347
|
+
# Kept on the async Connection (not ConnectionMixin): lazy connect leaves
|
|
348
|
+
# conn_handle=None until connect(), so we use _ever_opened to distinguish
|
|
349
|
+
# "never opened" (False) from "opened then closed" (True). Sync Connection
|
|
350
|
+
# allocates a handle in __init__ and does not need this guard.
|
|
351
|
+
if self.conn_handle is None:
|
|
352
|
+
return self._ever_opened
|
|
353
|
+
try:
|
|
354
|
+
response = core_driver.connection_is_closed(conn_handle=self.conn_handle)
|
|
355
|
+
return bool(response.is_closed)
|
|
356
|
+
except Exception:
|
|
357
|
+
return True
|
|
358
|
+
|
|
359
|
+
async def is_valid(self) -> bool:
|
|
360
|
+
if self.conn_handle is None or self.is_closed():
|
|
361
|
+
return False
|
|
362
|
+
try:
|
|
363
|
+
response = await async_core_driver.connection_heartbeat(conn_handle=self.conn_handle)
|
|
364
|
+
return bool(response.valid)
|
|
365
|
+
except Exception:
|
|
366
|
+
return False
|
|
367
|
+
|
|
368
|
+
# ------------------------------------------------------------------
|
|
369
|
+
# Cursors
|
|
370
|
+
# ------------------------------------------------------------------
|
|
371
|
+
|
|
372
|
+
@overload
|
|
373
|
+
def cursor(self, cursor_class: None = None) -> SnowflakeCursor: ...
|
|
374
|
+
|
|
375
|
+
@overload
|
|
376
|
+
def cursor(self, cursor_class: type[_CursorClsT]) -> _CursorClsT: ...
|
|
377
|
+
|
|
378
|
+
@pep249
|
|
379
|
+
@api_telemetry
|
|
380
|
+
@requires_open
|
|
381
|
+
def cursor(self, cursor_class: type[SnowflakeCursorBase] | None = None) -> Any:
|
|
382
|
+
"""Return a new Cursor object using the connection.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
cursor_class: The class to instantiate. Defaults to the
|
|
386
|
+
connection's ``SnowflakeCursor``; pass ``DictCursor`` to get
|
|
387
|
+
results as dictionaries.
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
A new cursor object.
|
|
391
|
+
"""
|
|
392
|
+
return self._instantiate_cursor(cursor_class)
|
|
393
|
+
|
|
394
|
+
# ------------------------------------------------------------------
|
|
395
|
+
# Multi-statement execution
|
|
396
|
+
# ------------------------------------------------------------------
|
|
397
|
+
|
|
398
|
+
@api_telemetry
|
|
399
|
+
async def execute_string(
|
|
400
|
+
self,
|
|
401
|
+
sql_text: str,
|
|
402
|
+
remove_comments: bool = False,
|
|
403
|
+
return_cursors: bool = True,
|
|
404
|
+
cursor_class: CursorType = SnowflakeCursor,
|
|
405
|
+
**kwargs: Any,
|
|
406
|
+
) -> Iterable[CursorInstance]:
|
|
407
|
+
stream = StringIO(sql_text)
|
|
408
|
+
stream_generator = self.execute_stream(
|
|
409
|
+
stream,
|
|
410
|
+
remove_comments=remove_comments,
|
|
411
|
+
cursor_class=cursor_class,
|
|
412
|
+
**kwargs,
|
|
413
|
+
)
|
|
414
|
+
if return_cursors:
|
|
415
|
+
return [cursor async for cursor in stream_generator]
|
|
416
|
+
async for _ in stream_generator:
|
|
417
|
+
pass
|
|
418
|
+
return []
|
|
419
|
+
|
|
420
|
+
@api_telemetry
|
|
421
|
+
async def execute_stream(
|
|
422
|
+
self,
|
|
423
|
+
stream: StringIO,
|
|
424
|
+
remove_comments: bool = False,
|
|
425
|
+
cursor_class: CursorType = SnowflakeCursor,
|
|
426
|
+
**kwargs: Any,
|
|
427
|
+
) -> AsyncGenerator[CursorInstance, None]:
|
|
428
|
+
for sql, is_put_or_get in split_statements(stream, remove_comments=remove_comments):
|
|
429
|
+
if not sql:
|
|
430
|
+
continue
|
|
431
|
+
cur = self.cursor(cursor_class=cursor_class)
|
|
432
|
+
await cur.execute(sql, _is_put_get=is_put_or_get, **kwargs)
|
|
433
|
+
yield cur
|
|
434
|
+
|
|
435
|
+
# ------------------------------------------------------------------
|
|
436
|
+
# Internal API
|
|
437
|
+
# ------------------------------------------------------------------
|
|
438
|
+
|
|
439
|
+
@property
|
|
440
|
+
@internal_api
|
|
441
|
+
@backward_compatibility
|
|
442
|
+
def _telemetry(self) -> AsyncTelemetryClient | None:
|
|
443
|
+
return self._telemetry_client
|
|
444
|
+
|
|
445
|
+
# ------------------------------------------------------------------
|
|
446
|
+
# Session info
|
|
447
|
+
# ------------------------------------------------------------------
|
|
448
|
+
|
|
449
|
+
@api_telemetry
|
|
450
|
+
def fetch_info(self, field: str) -> Any:
|
|
451
|
+
"""Fetch a single connection-info field by name."""
|
|
452
|
+
return self._connection_info[field]
|
|
453
|
+
|
|
454
|
+
@property
|
|
455
|
+
def _errorhandler_connection(self) -> Connection:
|
|
456
|
+
return self
|
|
457
|
+
|
|
458
|
+
# ------------------------------------------------------------------
|
|
459
|
+
# Server metadata
|
|
460
|
+
# ------------------------------------------------------------------
|
|
461
|
+
|
|
462
|
+
@api_telemetry
|
|
463
|
+
async def snowflake_version(self) -> str:
|
|
464
|
+
cur = self.cursor(DictCursor)
|
|
465
|
+
async with cur:
|
|
466
|
+
await cur.execute(CURRENT_VERSION_SQL)
|
|
467
|
+
row: dict[str, Any] = await cur.fetchone() # type: ignore[assignment]
|
|
468
|
+
return str(row["VERSION"]).split(" ")[0]
|
|
469
|
+
|
|
470
|
+
# ------------------------------------------------------------------
|
|
471
|
+
# Query status
|
|
472
|
+
# ------------------------------------------------------------------
|
|
473
|
+
|
|
474
|
+
@api_telemetry
|
|
475
|
+
async def get_query_status(self, sf_qid: str) -> QueryStatus:
|
|
476
|
+
status, _ = await self._get_query_status_with_response(sf_qid)
|
|
477
|
+
return status
|
|
478
|
+
|
|
479
|
+
@api_telemetry
|
|
480
|
+
async def get_query_status_throw_if_error(self, sf_qid: str) -> QueryStatus:
|
|
481
|
+
status, response = await self._get_query_status_with_response(sf_qid)
|
|
482
|
+
if self.is_an_error(status):
|
|
483
|
+
message = response.error_message if response.HasField("error_message") else f"Query {sf_qid} failed"
|
|
484
|
+
errno = response.error_code if response.HasField("error_code") else -1
|
|
485
|
+
raise ProgrammingError(msg=message, errno=errno, sfqid=sf_qid)
|
|
486
|
+
return status
|
|
487
|
+
|
|
488
|
+
async def _get_query_status_with_response(
|
|
489
|
+
self, sf_qid: str
|
|
490
|
+
) -> tuple[QueryStatus, ConnectionGetQueryStatusResponse]:
|
|
491
|
+
validate_query_id(sf_qid)
|
|
492
|
+
if self.conn_handle is None or self.is_closed():
|
|
493
|
+
return QueryStatus.DISCONNECTED, ConnectionGetQueryStatusResponse()
|
|
494
|
+
response = await async_core_driver.connection_get_query_status(
|
|
495
|
+
conn_handle=self.conn_handle,
|
|
496
|
+
query_id=sf_qid,
|
|
497
|
+
)
|
|
498
|
+
try:
|
|
499
|
+
status = QueryStatus[response.status_name]
|
|
500
|
+
except KeyError:
|
|
501
|
+
logger.warning("Unknown query status %r; treating as NO_DATA", response.status_name)
|
|
502
|
+
status = QueryStatus.NO_DATA
|
|
503
|
+
return status, response
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
SnowflakeConnection = Connection
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PEP 249 Database API 2.0 Cursor Objects (async)
|
|
3
|
+
|
|
4
|
+
This package defines the async cursor classes as specified in PEP 249.
|
|
5
|
+
|
|
6
|
+
Hierarchy:
|
|
7
|
+
SnowflakeCursorBase
|
|
8
|
+
├── SnowflakeCursor — returns tuple rows
|
|
9
|
+
└── DictCursor — returns dict rows
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from ..._internal.cursor import DictRow, QueryResultStats, ResultMetadata, ResultMetadataV2, Row
|
|
15
|
+
from ._base import SnowflakeCursorBase
|
|
16
|
+
from ._dict_cursor import DictCursor
|
|
17
|
+
from ._snowflake_cursor import SnowflakeCursor
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
CursorType = type[SnowflakeCursor] | type[DictCursor]
|
|
21
|
+
CursorInstance = SnowflakeCursor | DictCursor
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"CursorInstance",
|
|
26
|
+
"CursorType",
|
|
27
|
+
"DictCursor",
|
|
28
|
+
"DictRow",
|
|
29
|
+
"QueryResultStats",
|
|
30
|
+
"ResultMetadata",
|
|
31
|
+
"ResultMetadataV2",
|
|
32
|
+
"Row",
|
|
33
|
+
"SnowflakeCursor",
|
|
34
|
+
"SnowflakeCursorBase",
|
|
35
|
+
]
|