e6data-python-connector 2.3.10rc2__tar.gz → 2.3.10rc4__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.
- {e6data_python_connector-2.3.10rc2/e6data_python_connector.egg-info → e6data_python_connector-2.3.10rc4}/PKG-INFO +2 -2
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/README.md +1 -1
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/e6data_grpc.py +81 -37
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4/e6data_python_connector.egg-info}/PKG-INFO +2 -2
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/setup.py +1 -1
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/LICENSE +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/MANIFEST.in +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/__init__.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/cluster_manager.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/cluster_server/__init__.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/cluster_server/cluster_pb2.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/cluster_server/cluster_pb2_grpc.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/common.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/constants.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/datainputstream.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/date_time_utils.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/dialect.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/e6x_vector/__init__.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/e6x_vector/constants.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/e6x_vector/ttypes.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/exceptions.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/QueryEngineService.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/__init__.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/constants.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/e6x_engine_pb2.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/e6x_engine_pb2.pyi +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/e6x_engine_pb2_grpc.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/server/ttypes.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/strategy.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector/typeId.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector.egg-info/SOURCES.txt +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector.egg-info/dependency_links.txt +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector.egg-info/entry_points.txt +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector.egg-info/requires.txt +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/e6data_python_connector.egg-info/top_level.txt +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/pyproject.toml +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/setup.cfg +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/__init__.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_38_nines.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_all_cases.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_binary.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_correct_value.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_fields.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/check_decimal_errors.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/cleanup_test_files.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/debug_38_nines.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/debug_binary.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/final_test.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/move_tests.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/quick_test.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_38_nines.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_all_decimal128_cases.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_cluster_manager_efficiency.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_cluster_manager_none_strategy.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_cluster_manager_strategy.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_comprehensive.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_current_implementation.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_decimal128_binary_parsing.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_decimal128_parsing.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_fix.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_improved_parsing.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_known_case.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_manual_analysis.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_mock_server.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_multiprocessing_fix.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_new_implementation.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_specific_binary.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_strategy.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_strategy_logic.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_strategy_persistence_fix.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_strategy_sharing_fix.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_user_binary_value.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/tests.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/tests_grpc.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/validate_decimal128.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/validate_implementation.py +0 -0
- {e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/verify_decimal_fix.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: e6data-python-connector
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.10rc4
|
|
4
4
|
Summary: Client for the e6data distributed SQL Engine.
|
|
5
5
|
Home-page: https://github.com/e6x-labs/e6data-python-connector
|
|
6
6
|
Author: e6data, Inc.
|
|
@@ -38,7 +38,7 @@ Dynamic: summary
|
|
|
38
38
|
|
|
39
39
|
# e6data Python Connector
|
|
40
40
|
|
|
41
|
-

|
|
42
42
|
|
|
43
43
|
## Introduction
|
|
44
44
|
|
|
@@ -80,10 +80,12 @@ def re_auth(func):
|
|
|
80
80
|
if current_retry == max_retry:
|
|
81
81
|
raise e
|
|
82
82
|
if e.code() == grpc.StatusCode.INTERNAL and 'Access denied' in e.details():
|
|
83
|
+
_logger.debug(f'Re-authenticating due to {e}')
|
|
83
84
|
time.sleep(0.2)
|
|
84
85
|
self.connection.get_re_authenticate_session_id()
|
|
85
86
|
elif 'status: 456' in e.details():
|
|
86
87
|
# Strategy changed, clear cache and retry
|
|
88
|
+
_logger.debug(f'Re-authenticating due to status: 456')
|
|
87
89
|
_clear_strategy_cache()
|
|
88
90
|
# Force re-authentication which will detect new strategy
|
|
89
91
|
self.connection.get_re_authenticate_session_id()
|
|
@@ -243,7 +245,7 @@ def _invalidate_all_sessions():
|
|
|
243
245
|
shared_strategy['session_invalidated'] = True
|
|
244
246
|
|
|
245
247
|
|
|
246
|
-
def _register_query_strategy(query_id, strategy):
|
|
248
|
+
def _register_query_strategy(query_id, strategy, session_id=None):
|
|
247
249
|
"""Register the strategy used for a specific query."""
|
|
248
250
|
if not query_id or not strategy:
|
|
249
251
|
return
|
|
@@ -257,7 +259,8 @@ def _register_query_strategy(query_id, strategy):
|
|
|
257
259
|
query_map = shared_strategy.get('query_strategy_map', {})
|
|
258
260
|
query_map[query_id] = normalized_strategy
|
|
259
261
|
shared_strategy['query_strategy_map'] = query_map
|
|
260
|
-
|
|
262
|
+
session_info = f", session: {session_id}" if session_id else ""
|
|
263
|
+
_strategy_debug_log(f"Query {query_id} registered with strategy: {normalized_strategy}{session_info}")
|
|
261
264
|
|
|
262
265
|
|
|
263
266
|
def _get_query_strategy(query_id):
|
|
@@ -271,7 +274,7 @@ def _get_query_strategy(query_id):
|
|
|
271
274
|
return query_map.get(query_id, current_active_strategy)
|
|
272
275
|
|
|
273
276
|
|
|
274
|
-
def _cleanup_query_strategy(query_id):
|
|
277
|
+
def _cleanup_query_strategy(query_id, session_id=None):
|
|
275
278
|
"""Remove the strategy mapping for a completed query."""
|
|
276
279
|
if not query_id:
|
|
277
280
|
return
|
|
@@ -283,7 +286,8 @@ def _cleanup_query_strategy(query_id):
|
|
|
283
286
|
del query_map[query_id]
|
|
284
287
|
shared_strategy['query_strategy_map'] = query_map
|
|
285
288
|
remaining_queries = len(query_map)
|
|
286
|
-
|
|
289
|
+
session_info = f", session: {session_id}" if session_id else ""
|
|
290
|
+
_strategy_debug_log(f"Query {query_id} completed (was using {strategy}{session_info}). Remaining active queries: {remaining_queries}")
|
|
287
291
|
|
|
288
292
|
|
|
289
293
|
def _get_strategy_debug_info():
|
|
@@ -300,10 +304,18 @@ def _get_strategy_debug_info():
|
|
|
300
304
|
}
|
|
301
305
|
|
|
302
306
|
|
|
303
|
-
def _get_grpc_header(engine_ip=None, cluster=None, strategy=None):
|
|
307
|
+
def _get_grpc_header(engine_ip=None, cluster=None, strategy=None, session_id=None, request_type=None):
|
|
304
308
|
"""Generate gRPC metadata headers for the request."""
|
|
305
309
|
# Use the strategy module's implementation
|
|
306
|
-
|
|
310
|
+
headers = _get_strategy_header(engine_ip=engine_ip, cluster=cluster, strategy=strategy)
|
|
311
|
+
|
|
312
|
+
# Log headers being sent if debug connections exist
|
|
313
|
+
if _debug_connections:
|
|
314
|
+
session_info = f", session: {session_id}" if session_id else ""
|
|
315
|
+
request_info = f" [{request_type}]" if request_type else ""
|
|
316
|
+
_strategy_debug_log(f"Sending headers{request_info}: strategy={strategy}, cluster={cluster}, engine_ip={engine_ip}{session_info}")
|
|
317
|
+
|
|
318
|
+
return headers
|
|
307
319
|
|
|
308
320
|
|
|
309
321
|
def connect(*args, **kwargs):
|
|
@@ -518,9 +530,11 @@ class Connection(object):
|
|
|
518
530
|
# Check if session strategy matches current active strategy
|
|
519
531
|
elif self._session_id and self._session_strategy and self._session_strategy != _get_active_strategy():
|
|
520
532
|
# Session was created with different strategy, need to re-authenticate
|
|
521
|
-
_strategy_debug_log(f"Session strategy mismatch: session created with {self._session_strategy}, current active is {_get_active_strategy()}")
|
|
533
|
+
_strategy_debug_log(f"Session strategy mismatch: session {self._session_id} created with {self._session_strategy}, current active is {_get_active_strategy()}")
|
|
534
|
+
old_session_id = self._session_id
|
|
522
535
|
self._session_id = None
|
|
523
536
|
self._session_strategy = None
|
|
537
|
+
_strategy_debug_log(f"Invalidating session {old_session_id} due to strategy mismatch")
|
|
524
538
|
self.close()
|
|
525
539
|
self._create_client()
|
|
526
540
|
|
|
@@ -538,32 +552,37 @@ class Connection(object):
|
|
|
538
552
|
|
|
539
553
|
if active_strategy and not pending_strategy:
|
|
540
554
|
# Use cached strategy only if there's no pending strategy
|
|
541
|
-
_strategy_debug_log(f"Authenticating with cached strategy: {active_strategy}")
|
|
555
|
+
_strategy_debug_log(f"Authenticating with cached strategy: {active_strategy} (session: {self._session_id})")
|
|
542
556
|
try:
|
|
543
557
|
authenticate_response = self._client.authenticate(
|
|
544
558
|
authenticate_request,
|
|
545
|
-
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=active_strategy
|
|
559
|
+
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=active_strategy,
|
|
560
|
+
session_id=self._session_id, request_type="authenticate")
|
|
546
561
|
)
|
|
547
562
|
self._session_id = authenticate_response.sessionId
|
|
548
563
|
if not self._session_id:
|
|
549
564
|
raise ValueError("Invalid credentials.")
|
|
550
565
|
# Track which strategy was used for this session
|
|
551
566
|
self._session_strategy = active_strategy
|
|
567
|
+
_strategy_debug_log(f"Authentication successful with strategy: {active_strategy}, session: {self._session_id}")
|
|
552
568
|
# Check for new strategy in authenticate response
|
|
553
569
|
if hasattr(authenticate_response, 'new_strategy') and authenticate_response.new_strategy:
|
|
554
570
|
new_strategy = authenticate_response.new_strategy.lower()
|
|
555
571
|
if new_strategy != active_strategy:
|
|
572
|
+
_strategy_debug_log(f"Strategy changed from {active_strategy} to {new_strategy} in authenticate response, session: {self._session_id}")
|
|
556
573
|
_set_pending_strategy(new_strategy)
|
|
557
574
|
_apply_pending_strategy()
|
|
575
|
+
old_session_id = self._session_id
|
|
558
576
|
self._session_id = None
|
|
559
577
|
self._session_strategy = None
|
|
578
|
+
_strategy_debug_log(f"Resetting session {old_session_id} due to new strategy: {new_strategy}")
|
|
560
579
|
self.close()
|
|
561
580
|
self._create_client()
|
|
562
581
|
return self.get_session_id
|
|
563
582
|
except _InactiveRpcError as e:
|
|
564
583
|
if e.code() == grpc.StatusCode.UNKNOWN and 'status: 456' in e.details():
|
|
565
584
|
# Strategy changed, clear cache and retry
|
|
566
|
-
_strategy_debug_log(f"Got 456 error with strategy {active_strategy}, clearing cache and retrying")
|
|
585
|
+
_strategy_debug_log(f"Got 456 error with strategy {active_strategy}, session: {self._session_id}, clearing cache and retrying")
|
|
567
586
|
_clear_strategy_cache()
|
|
568
587
|
active_strategy = None
|
|
569
588
|
else:
|
|
@@ -585,16 +604,17 @@ class Connection(object):
|
|
|
585
604
|
_strategy_debug_log(f"No cached strategy, will try strategies in order: {strategies}")
|
|
586
605
|
last_error = None
|
|
587
606
|
for strategy in strategies:
|
|
588
|
-
_strategy_debug_log(f"Attempting authentication with strategy: {strategy}")
|
|
607
|
+
_strategy_debug_log(f"Attempting authentication with strategy: {strategy} (no session yet)")
|
|
589
608
|
try:
|
|
590
609
|
authenticate_response = self._client.authenticate(
|
|
591
610
|
authenticate_request,
|
|
592
|
-
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=strategy
|
|
611
|
+
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=strategy,
|
|
612
|
+
session_id=None, request_type="authenticate")
|
|
593
613
|
)
|
|
594
614
|
self._session_id = authenticate_response.sessionId
|
|
595
615
|
if self._session_id:
|
|
596
616
|
# Success! Cache this strategy
|
|
597
|
-
_strategy_debug_log(f"Authentication successful with strategy: {strategy}")
|
|
617
|
+
_strategy_debug_log(f"Authentication successful with strategy: {strategy}, session: {self._session_id}")
|
|
598
618
|
_set_active_strategy(strategy)
|
|
599
619
|
# Track which strategy was used for this session
|
|
600
620
|
self._session_strategy = strategy
|
|
@@ -603,9 +623,12 @@ class Connection(object):
|
|
|
603
623
|
if hasattr(authenticate_response, 'new_strategy') and authenticate_response.new_strategy:
|
|
604
624
|
new_strategy = authenticate_response.new_strategy.lower()
|
|
605
625
|
if new_strategy != strategy:
|
|
626
|
+
_strategy_debug_log(f"Strategy changed from {strategy} to {new_strategy} in authenticate response, session: {self._session_id}")
|
|
606
627
|
_set_pending_strategy(new_strategy)
|
|
607
628
|
_apply_pending_strategy()
|
|
629
|
+
old_session_id = self._session_id
|
|
608
630
|
self.close()
|
|
631
|
+
_strategy_debug_log(f"Resetting session {old_session_id} due to new strategy: {new_strategy}")
|
|
609
632
|
self._create_client()
|
|
610
633
|
self._session_id = None
|
|
611
634
|
self._session_strategy = None
|
|
@@ -614,7 +637,7 @@ class Connection(object):
|
|
|
614
637
|
except _InactiveRpcError as e:
|
|
615
638
|
if e.code() == grpc.StatusCode.UNKNOWN and 'status: 456' in e.details():
|
|
616
639
|
# Wrong strategy, try the next one
|
|
617
|
-
_strategy_debug_log(f"Strategy {strategy} failed with 456 error, trying next")
|
|
640
|
+
_strategy_debug_log(f"Strategy {strategy} failed with 456 error (session attempt failed), trying next")
|
|
618
641
|
last_error = e
|
|
619
642
|
continue
|
|
620
643
|
else:
|
|
@@ -682,6 +705,7 @@ class Connection(object):
|
|
|
682
705
|
|
|
683
706
|
This method ensures that the gRPC channel is properly closed and the session ID is reset to None.
|
|
684
707
|
"""
|
|
708
|
+
old_session = self._session_id
|
|
685
709
|
if self._channel is not None:
|
|
686
710
|
self._channel.close()
|
|
687
711
|
self._channel = None
|
|
@@ -691,7 +715,8 @@ class Connection(object):
|
|
|
691
715
|
# Remove from debug connections if debug was enabled
|
|
692
716
|
if self._debug:
|
|
693
717
|
_debug_connections.discard(id(self))
|
|
694
|
-
|
|
718
|
+
session_info = f", session was: {old_session}" if old_session else ""
|
|
719
|
+
_strategy_debug_log(f"Debug mode disabled for connection {id(self)}{session_info}")
|
|
695
720
|
|
|
696
721
|
def check_connection(self):
|
|
697
722
|
"""
|
|
@@ -754,7 +779,8 @@ class Connection(object):
|
|
|
754
779
|
)
|
|
755
780
|
clear_response = self._client.clear(
|
|
756
781
|
clear_request,
|
|
757
|
-
metadata=_get_grpc_header(engine_ip=engine_ip, cluster=self.cluster_name, strategy=_get_active_strategy()
|
|
782
|
+
metadata=_get_grpc_header(engine_ip=engine_ip, cluster=self.cluster_name, strategy=_get_active_strategy(),
|
|
783
|
+
session_id=self.connection.get_session_id, request_type="clear")
|
|
758
784
|
)
|
|
759
785
|
|
|
760
786
|
# Check for new strategy in clear response
|
|
@@ -785,7 +811,8 @@ class Connection(object):
|
|
|
785
811
|
)
|
|
786
812
|
cancel_response = self._client.cancelQuery(
|
|
787
813
|
cancel_query_request,
|
|
788
|
-
metadata=_get_grpc_header(engine_ip=engine_ip, cluster=self.cluster_name, strategy=_get_active_strategy()
|
|
814
|
+
metadata=_get_grpc_header(engine_ip=engine_ip, cluster=self.cluster_name, strategy=_get_active_strategy(),
|
|
815
|
+
session_id=self._session_id, request_type="query_cancel")
|
|
789
816
|
)
|
|
790
817
|
|
|
791
818
|
# Check for new strategy in cancel response
|
|
@@ -809,7 +836,8 @@ class Connection(object):
|
|
|
809
836
|
)
|
|
810
837
|
dry_run_response = self._client.dryRun(
|
|
811
838
|
dry_run_request,
|
|
812
|
-
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy()
|
|
839
|
+
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy(),
|
|
840
|
+
session_id=self.get_session_id, request_type="dry_run")
|
|
813
841
|
)
|
|
814
842
|
return dry_run_response.dryrunValue
|
|
815
843
|
|
|
@@ -831,7 +859,8 @@ class Connection(object):
|
|
|
831
859
|
)
|
|
832
860
|
get_table_response = self._client.getTablesV2(
|
|
833
861
|
get_table_request,
|
|
834
|
-
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy()
|
|
862
|
+
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy(),
|
|
863
|
+
session_id=self.get_session_id, request_type="get_tables")
|
|
835
864
|
)
|
|
836
865
|
|
|
837
866
|
# Check for new strategy in get tables response
|
|
@@ -859,7 +888,8 @@ class Connection(object):
|
|
|
859
888
|
)
|
|
860
889
|
get_columns_response = self._client.getColumnsV2(
|
|
861
890
|
get_columns_request,
|
|
862
|
-
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy()
|
|
891
|
+
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy(),
|
|
892
|
+
session_id=self.get_session_id, request_type="get_columns")
|
|
863
893
|
)
|
|
864
894
|
|
|
865
895
|
# Check for new strategy in get columns response
|
|
@@ -883,7 +913,8 @@ class Connection(object):
|
|
|
883
913
|
)
|
|
884
914
|
get_schema_response = self._client.getSchemaNamesV2(
|
|
885
915
|
get_schema_request,
|
|
886
|
-
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy()
|
|
916
|
+
metadata=_get_grpc_header(cluster=self.cluster_name, strategy=_get_active_strategy(),
|
|
917
|
+
session_id=self.get_session_id, request_type="get_schema")
|
|
887
918
|
)
|
|
888
919
|
|
|
889
920
|
# Check for new strategy in get schema names response
|
|
@@ -970,10 +1001,12 @@ class Cursor(DBAPICursor):
|
|
|
970
1001
|
"""Reset state about the previous query in preparation for running another query"""
|
|
971
1002
|
pass
|
|
972
1003
|
|
|
973
|
-
|
|
974
|
-
def metadata(self):
|
|
1004
|
+
def _get_metadata(self, request_type="query_operation"):
|
|
975
1005
|
"""
|
|
976
|
-
Get the gRPC metadata for the current query.
|
|
1006
|
+
Get the gRPC metadata for the current query with specific request type.
|
|
1007
|
+
|
|
1008
|
+
Args:
|
|
1009
|
+
request_type (str): The type of request being made
|
|
977
1010
|
|
|
978
1011
|
Returns:
|
|
979
1012
|
list: A list of tuples containing gRPC metadata.
|
|
@@ -986,7 +1019,18 @@ class Cursor(DBAPICursor):
|
|
|
986
1019
|
strategy = self.connection._session_strategy
|
|
987
1020
|
else:
|
|
988
1021
|
strategy = _get_active_strategy()
|
|
989
|
-
return _get_grpc_header(engine_ip=self._engine_ip, cluster=self.connection.cluster_name, strategy=strategy
|
|
1022
|
+
return _get_grpc_header(engine_ip=self._engine_ip, cluster=self.connection.cluster_name, strategy=strategy,
|
|
1023
|
+
session_id=self.connection.get_session_id, request_type=request_type)
|
|
1024
|
+
|
|
1025
|
+
@property
|
|
1026
|
+
def metadata(self):
|
|
1027
|
+
"""
|
|
1028
|
+
Get the gRPC metadata for the current query.
|
|
1029
|
+
|
|
1030
|
+
Returns:
|
|
1031
|
+
list: A list of tuples containing gRPC metadata.
|
|
1032
|
+
"""
|
|
1033
|
+
return self._get_metadata("query_operation")
|
|
990
1034
|
|
|
991
1035
|
@property
|
|
992
1036
|
def arraysize(self):
|
|
@@ -1128,7 +1172,7 @@ class Cursor(DBAPICursor):
|
|
|
1128
1172
|
)
|
|
1129
1173
|
# Get fresh client after session access (may have been invalidated)
|
|
1130
1174
|
client = self.connection.client
|
|
1131
|
-
clear_response = client.clearOrCancelQuery(clear_request, metadata=self.
|
|
1175
|
+
clear_response = client.clearOrCancelQuery(clear_request, metadata=self._get_metadata("clear_or_cancel"))
|
|
1132
1176
|
|
|
1133
1177
|
# Check for new strategy in clear response
|
|
1134
1178
|
if hasattr(clear_response, 'new_strategy') and clear_response.new_strategy:
|
|
@@ -1136,7 +1180,7 @@ class Cursor(DBAPICursor):
|
|
|
1136
1180
|
|
|
1137
1181
|
# Clean up query strategy mapping
|
|
1138
1182
|
if query_id:
|
|
1139
|
-
_cleanup_query_strategy(query_id)
|
|
1183
|
+
_cleanup_query_strategy(query_id, self.connection.get_session_id)
|
|
1140
1184
|
|
|
1141
1185
|
# Check if this was the last query and we have a pending strategy
|
|
1142
1186
|
shared_strategy = _get_shared_strategy()
|
|
@@ -1144,7 +1188,7 @@ class Cursor(DBAPICursor):
|
|
|
1144
1188
|
query_map = shared_strategy.get('query_strategy_map', {})
|
|
1145
1189
|
|
|
1146
1190
|
if pending_strategy and len(query_map) == 0:
|
|
1147
|
-
_strategy_debug_log(f"Last query cleared, triggering pending strategy transition")
|
|
1191
|
+
_strategy_debug_log(f"Last query cleared for session {self.connection.get_session_id}, triggering pending strategy transition from {_get_active_strategy()} to {pending_strategy}")
|
|
1148
1192
|
_apply_pending_strategy()
|
|
1149
1193
|
|
|
1150
1194
|
return clear_response
|
|
@@ -1160,7 +1204,7 @@ class Cursor(DBAPICursor):
|
|
|
1160
1204
|
self.connection.query_cancel(engine_ip=self._engine_ip, query_id=query_id)
|
|
1161
1205
|
|
|
1162
1206
|
if query_id:
|
|
1163
|
-
_cleanup_query_strategy(query_id)
|
|
1207
|
+
_cleanup_query_strategy(query_id, self.connection.get_session_id)
|
|
1164
1208
|
|
|
1165
1209
|
# Check if this was the last query and we have a pending strategy
|
|
1166
1210
|
shared_strategy = _get_shared_strategy()
|
|
@@ -1168,7 +1212,7 @@ class Cursor(DBAPICursor):
|
|
|
1168
1212
|
query_map = shared_strategy.get('query_strategy_map', {})
|
|
1169
1213
|
|
|
1170
1214
|
if pending_strategy and len(query_map) == 0:
|
|
1171
|
-
_strategy_debug_log(f"Last query cleared, triggering pending strategy transition")
|
|
1215
|
+
_strategy_debug_log(f"Last query cleared for session {self.connection.get_session_id}, triggering pending strategy transition from {_get_active_strategy()} to {pending_strategy}")
|
|
1172
1216
|
_apply_pending_strategy()
|
|
1173
1217
|
|
|
1174
1218
|
def status(self, query_id):
|
|
@@ -1186,7 +1230,7 @@ class Cursor(DBAPICursor):
|
|
|
1186
1230
|
queryId=query_id,
|
|
1187
1231
|
engineIP=self._engine_ip
|
|
1188
1232
|
)
|
|
1189
|
-
status_response = self.connection.client.status(status_request, metadata=self.
|
|
1233
|
+
status_response = self.connection.client.status(status_request, metadata=self._get_metadata("status"))
|
|
1190
1234
|
|
|
1191
1235
|
# Check for new strategy in status response
|
|
1192
1236
|
if hasattr(status_response, 'new_strategy') and status_response.new_strategy:
|
|
@@ -1227,7 +1271,7 @@ class Cursor(DBAPICursor):
|
|
|
1227
1271
|
client = self.connection.client
|
|
1228
1272
|
prepare_statement_response = client.prepareStatement(
|
|
1229
1273
|
prepare_statement_request,
|
|
1230
|
-
metadata=self.
|
|
1274
|
+
metadata=self._get_metadata("prepare_statement")
|
|
1231
1275
|
)
|
|
1232
1276
|
|
|
1233
1277
|
self._query_id = prepare_statement_response.queryId
|
|
@@ -1242,7 +1286,7 @@ class Cursor(DBAPICursor):
|
|
|
1242
1286
|
# Register this query with the current strategy
|
|
1243
1287
|
current_strategy = _get_active_strategy()
|
|
1244
1288
|
if current_strategy:
|
|
1245
|
-
_register_query_strategy(self._query_id, current_strategy)
|
|
1289
|
+
_register_query_strategy(self._query_id, current_strategy, self.connection.get_session_id)
|
|
1246
1290
|
|
|
1247
1291
|
execute_statement_request = e6x_engine_pb2.ExecuteStatementRequest(
|
|
1248
1292
|
engineIP=self._engine_ip,
|
|
@@ -1253,7 +1297,7 @@ class Cursor(DBAPICursor):
|
|
|
1253
1297
|
client = self.connection.client
|
|
1254
1298
|
execute_response = client.executeStatement(
|
|
1255
1299
|
execute_statement_request,
|
|
1256
|
-
metadata=self.
|
|
1300
|
+
metadata=self._get_metadata("execute_statement")
|
|
1257
1301
|
)
|
|
1258
1302
|
|
|
1259
1303
|
# Check for new strategy in execute response
|
|
@@ -1272,7 +1316,7 @@ class Cursor(DBAPICursor):
|
|
|
1272
1316
|
client = self.connection.client
|
|
1273
1317
|
prepare_statement_response = client.prepareStatementV2(
|
|
1274
1318
|
prepare_statement_request,
|
|
1275
|
-
metadata=self.
|
|
1319
|
+
metadata=self._get_metadata("prepare_statement_v2"),
|
|
1276
1320
|
timeout=self.connection.grpc_prepare_timeout
|
|
1277
1321
|
)
|
|
1278
1322
|
|
|
@@ -1289,7 +1333,7 @@ class Cursor(DBAPICursor):
|
|
|
1289
1333
|
current_strategy = _get_active_strategy()
|
|
1290
1334
|
|
|
1291
1335
|
if current_strategy:
|
|
1292
|
-
_register_query_strategy(self._query_id, current_strategy)
|
|
1336
|
+
_register_query_strategy(self._query_id, current_strategy, self.connection.get_session_id)
|
|
1293
1337
|
|
|
1294
1338
|
execute_statement_request = e6x_engine_pb2.ExecuteStatementV2Request(
|
|
1295
1339
|
engineIP=self._engine_ip,
|
|
@@ -1300,7 +1344,7 @@ class Cursor(DBAPICursor):
|
|
|
1300
1344
|
client = self.connection.client
|
|
1301
1345
|
execute_response = client.executeStatementV2(
|
|
1302
1346
|
execute_statement_request,
|
|
1303
|
-
metadata=self.
|
|
1347
|
+
metadata=self._get_metadata("execute_statement_v2")
|
|
1304
1348
|
)
|
|
1305
1349
|
|
|
1306
1350
|
# Check for new strategy in execute response
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: e6data-python-connector
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.10rc4
|
|
4
4
|
Summary: Client for the e6data distributed SQL Engine.
|
|
5
5
|
Home-page: https://github.com/e6x-labs/e6data-python-connector
|
|
6
6
|
Author: e6data, Inc.
|
|
@@ -38,7 +38,7 @@ Dynamic: summary
|
|
|
38
38
|
|
|
39
39
|
# e6data Python Connector
|
|
40
40
|
|
|
41
|
-

|
|
42
42
|
|
|
43
43
|
## Introduction
|
|
44
44
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_38_nines.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_all_cases.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_binary.py
RENAMED
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/analyze_fields.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/check_decimal_errors.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/cleanup_test_files.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/debug_38_nines.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/debug_binary.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_38_nines.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_comprehensive.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_known_case.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_manual_analysis.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_mock_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_specific_binary.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_strategy.py
RENAMED
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/test_strategy_logic.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/validate_decimal128.py
RENAMED
|
File without changes
|
|
File without changes
|
{e6data_python_connector-2.3.10rc2 → e6data_python_connector-2.3.10rc4}/test/verify_decimal_fix.py
RENAMED
|
File without changes
|