Skip to content

Commit 676c42a

Browse files
Add defer_connect config to allow eagerly verifying connection
This commit adds a new connection parameter `defer_connect` which can be set to False to force creating a connection when `trino.dbapi.connect` is called. Any connection errors as a result of that get rewrapped into `trino.exceptions.TrinoConnectionError`. By default `defer_connect` is set to `True` so users can explicitly call `trino.dbapi.Connection.connect` to do the connection check. This doesn't end up actually executing a query on the server because after the initial POST request the nextUri in the response is not followed which leaves the query in QUEUED state. This is not documented in the Trino REST API but the server does behave like this today. The benefit is that we can very cheaply verify if the connection is valid without polluting the server's query history or adding queries to queue.
1 parent 6eaef4b commit 676c42a

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

trino/dbapi.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
from typing import Any, Dict, List, NamedTuple, Optional # NOQA for mypy types
2929
from urllib.parse import urlparse
3030

31+
from requests.exceptions import RequestException
32+
3133
try:
3234
from zoneinfo import ZoneInfo
3335
except ModuleNotFoundError:
@@ -157,6 +159,7 @@ def __init__(
157159
legacy_prepared_statements=None,
158160
roles=None,
159161
timezone=None,
162+
defer_connect=True,
160163
):
161164
# Automatically assign http_schema, port based on hostname
162165
parsed_host = urlparse(host, allow_fragments=False)
@@ -201,6 +204,36 @@ def __init__(
201204
self.legacy_primitive_types = legacy_primitive_types
202205
self.legacy_prepared_statements = legacy_prepared_statements
203206

207+
if not defer_connect:
208+
self.connect()
209+
210+
def connect(self) -> None:
211+
connection_test_request = trino.client.TrinoRequest(
212+
self.host,
213+
self.port,
214+
self._client_session,
215+
self._http_session,
216+
self.http_scheme,
217+
self.auth,
218+
self.redirect_handler,
219+
self.max_attempts,
220+
self.request_timeout,
221+
verify=self._http_session.verify,
222+
)
223+
try:
224+
test_response = connection_test_request.post("<not-going-to-be-executed>")
225+
if not test_response.ok:
226+
raise trino.exceptions.TrinoConnectionError(
227+
"error {}{}".format(
228+
test_response.status_code,
229+
": {}".format(test_response.content)
230+
if test_response.content
231+
else "",
232+
)
233+
)
234+
except RequestException as e:
235+
raise trino.exceptions.TrinoConnectionError("connection failed: {}".format(e))
236+
204237
@property
205238
def isolation_level(self):
206239
return self._isolation_level

0 commit comments

Comments
 (0)