e6data-python-connector 2.3.11rc1__tar.gz → 2.3.12__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.11rc1/e6data_python_connector.egg-info → e6data_python_connector-2.3.12}/PKG-INFO +171 -2
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/README.md +170 -1
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/cluster_manager.py +99 -30
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/common.py +44 -0
- e6data_python_connector-2.3.12/e6data_python_connector/constants.py +56 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/datainputstream.py +24 -7
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/e6data_grpc.py +113 -47
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12/e6data_python_connector.egg-info}/PKG-INFO +171 -2
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector.egg-info/SOURCES.txt +4 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/setup.py +1 -1
- e6data_python_connector-2.3.12/test/benchmark_fastbinary_performance.py +303 -0
- e6data_python_connector-2.3.12/test/test_code_optimizations.py +322 -0
- e6data_python_connector-2.3.12/test/test_optimizations_integration.py +443 -0
- e6data_python_connector-2.3.12/test/test_ssl_cert.py +548 -0
- e6data_python_connector-2.3.11rc1/e6data_python_connector/constants.py +0 -32
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/LICENSE +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/MANIFEST.in +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/cluster_server/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/cluster_server/cluster_pb2.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/cluster_server/cluster_pb2_grpc.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/connection_pool.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/date_time_utils.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/dialect.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/e6x_vector/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/e6x_vector/constants.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/e6x_vector/ttypes.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/exceptions.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/QueryEngineService.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/constants.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/e6x_engine_pb2.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/e6x_engine_pb2.pyi +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/e6x_engine_pb2_grpc.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/server/ttypes.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/strategy.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector/typeId.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector.egg-info/dependency_links.txt +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector.egg-info/entry_points.txt +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector.egg-info/requires.txt +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/e6data_python_connector.egg-info/top_level.txt +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/gen-py/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/gen-py/e6x_vector/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/gen-py/e6x_vector/constants.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/gen-py/e6x_vector/ttypes.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/pyproject.toml +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/setup.cfg +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/__init__.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/analyze_38_nines.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/analyze_all_cases.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/analyze_binary.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/analyze_correct_value.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/analyze_fields.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/check_decimal_errors.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/cleanup_test_files.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/debug_38_nines.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/debug_binary.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/final_test.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/move_tests.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/quick_test.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_38_nines.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_all_decimal128_cases.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_cluster_manager_efficiency.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_cluster_manager_none_strategy.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_cluster_manager_strategy.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_comprehensive.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_connection_pool.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_connection_pool_e2e.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_current_implementation.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_decimal128_binary_parsing.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_decimal128_parsing.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_fix.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_improved_parsing.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_known_case.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_manual_analysis.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_mock_server.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_multiprocessing_fix.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_new_implementation.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_pool_concurrency_simple.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_pool_threading_multiprocessing.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_simple_connection_pool.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_specific_binary.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_strategy.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_strategy_logic.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_strategy_persistence_fix.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_strategy_sharing_fix.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/test_user_binary_value.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/tests.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/tests_grpc.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/validate_decimal128.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/test/validate_implementation.py +0 -0
- {e6data_python_connector-2.3.11rc1 → e6data_python_connector-2.3.12}/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.12
|
|
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.
|
|
@@ -39,7 +39,7 @@ Dynamic: summary
|
|
|
39
39
|
|
|
40
40
|
# e6data Python Connector
|
|
41
41
|
|
|
42
|
-

|
|
43
43
|
|
|
44
44
|
## Introduction
|
|
45
45
|
|
|
@@ -122,8 +122,11 @@ The `Connection` class supports the following parameters:
|
|
|
122
122
|
| `catalog` | str | No | None | Catalog name |
|
|
123
123
|
| `cluster_name` | str | No | None | Name of the cluster for cluster-specific operations |
|
|
124
124
|
| `secure` | bool | No | False | Enable SSL/TLS for secure connections |
|
|
125
|
+
| `ssl_cert` | str/bytes | No | None | Path to CA certificate (PEM) or certificate bytes for HTTPS connections |
|
|
125
126
|
| `auto_resume` | bool | No | True | Automatically resume cluster if suspended |
|
|
126
127
|
| `grpc_options` | dict | No | None | Additional gRPC configuration options |
|
|
128
|
+
| `debug` | bool | No | False | Enable debug logging for troubleshooting |
|
|
129
|
+
| `require_fastbinary` | bool | No | True | Require fastbinary module for Thrift deserialization. Set to False to use pure Python implementation if system dependencies cannot be installed |
|
|
127
130
|
|
|
128
131
|
#### Secure Connection Example
|
|
129
132
|
|
|
@@ -157,6 +160,117 @@ conn = Connection(
|
|
|
157
160
|
)
|
|
158
161
|
```
|
|
159
162
|
|
|
163
|
+
#### HTTPS Connection with HAProxy
|
|
164
|
+
|
|
165
|
+
When connecting through HAProxy with HTTPS, you can provide a custom CA certificate for secure connections. The `ssl_cert` parameter accepts either a file path to a PEM certificate or the certificate content as bytes.
|
|
166
|
+
|
|
167
|
+
**Using a CA certificate file path:**
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
conn = Connection(
|
|
171
|
+
host=host,
|
|
172
|
+
port=443,
|
|
173
|
+
username=username,
|
|
174
|
+
password=password,
|
|
175
|
+
database=database,
|
|
176
|
+
secure=True,
|
|
177
|
+
ssl_cert='/path/to/ca-cert.pem' # Path to your CA certificate
|
|
178
|
+
)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Reading certificate content as bytes:**
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
# Read certificate file and pass as bytes
|
|
185
|
+
with open('/path/to/ca-cert.pem', 'rb') as cert_file:
|
|
186
|
+
cert_data = cert_file.read()
|
|
187
|
+
|
|
188
|
+
conn = Connection(
|
|
189
|
+
host=host,
|
|
190
|
+
port=443,
|
|
191
|
+
username=username,
|
|
192
|
+
password=password,
|
|
193
|
+
database=database,
|
|
194
|
+
secure=True,
|
|
195
|
+
ssl_cert=cert_data # Certificate content as bytes
|
|
196
|
+
)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Using system CA bundle for publicly signed certificates:**
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
# When ssl_cert is None, system default CA bundle is used
|
|
203
|
+
conn = Connection(
|
|
204
|
+
host=host,
|
|
205
|
+
port=443,
|
|
206
|
+
username=username,
|
|
207
|
+
password=password,
|
|
208
|
+
database=database,
|
|
209
|
+
secure=True # Uses system CA bundle by default
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Connection pooling with custom CA certificate:**
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
pool = ConnectionPool(
|
|
217
|
+
min_size=2,
|
|
218
|
+
max_size=10,
|
|
219
|
+
host=host,
|
|
220
|
+
port=443,
|
|
221
|
+
username=username,
|
|
222
|
+
password=password,
|
|
223
|
+
database=database,
|
|
224
|
+
secure=True,
|
|
225
|
+
ssl_cert='/path/to/ca-cert.pem' # Custom CA certificate for pool connections
|
|
226
|
+
)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
#### Handling Missing System Dependencies
|
|
230
|
+
|
|
231
|
+
The e6data connector uses the `fastbinary` module (from Apache Thrift) for optimal performance when deserializing data. This module requires system-level dependencies (`python3-devel` and `gcc-c++`) to be installed.
|
|
232
|
+
|
|
233
|
+
**Default Behavior (Recommended):**
|
|
234
|
+
By default, the connector requires `fastbinary` to be available. If it's not found, the connection will fail immediately with a clear error message:
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
conn = Connection(
|
|
238
|
+
host=host,
|
|
239
|
+
port=port,
|
|
240
|
+
username=username,
|
|
241
|
+
password=password,
|
|
242
|
+
database=database
|
|
243
|
+
)
|
|
244
|
+
# Raises exception if fastbinary is not available
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Fallback to Pure Python:**
|
|
248
|
+
If you cannot install system dependencies (e.g., in restricted environments, serverless platforms, or containers without build tools), you can disable the `fastbinary` requirement. The connector will fall back to a pure Python implementation with a performance penalty:
|
|
249
|
+
|
|
250
|
+
```python
|
|
251
|
+
conn = Connection(
|
|
252
|
+
host=host,
|
|
253
|
+
port=port,
|
|
254
|
+
username=username,
|
|
255
|
+
password=password,
|
|
256
|
+
database=database,
|
|
257
|
+
require_fastbinary=False # Allow operation without fastbinary
|
|
258
|
+
)
|
|
259
|
+
# Logs warning but continues with pure Python implementation
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**When to use `require_fastbinary=False`:**
|
|
263
|
+
- Running in AWS Lambda or other serverless environments
|
|
264
|
+
- Docker containers built without compilation tools
|
|
265
|
+
- Restricted environments where system packages cannot be installed
|
|
266
|
+
- Development/testing environments where performance is not critical
|
|
267
|
+
|
|
268
|
+
**Performance Impact:**
|
|
269
|
+
- With `fastbinary`: Optimal performance for data deserialization
|
|
270
|
+
- Without `fastbinary` (pure Python): ~2-3x slower deserialization, but otherwise fully functional
|
|
271
|
+
|
|
272
|
+
**Note:** It's strongly recommended to install system dependencies when possible for best performance. The `require_fastbinary=False` option should only be used when system dependencies cannot be installed.
|
|
273
|
+
|
|
160
274
|
### Perform a Queries & Get Results
|
|
161
275
|
|
|
162
276
|
```python
|
|
@@ -637,4 +751,59 @@ conn.close()
|
|
|
637
751
|
- Graceful connection recovery and retry logic
|
|
638
752
|
- Blue-green deployment support with automatic failover
|
|
639
753
|
|
|
754
|
+
## Debugging and Troubleshooting
|
|
755
|
+
|
|
756
|
+
### Enable Debug Mode
|
|
757
|
+
|
|
758
|
+
Enable comprehensive debugging to troubleshoot connection and query issues:
|
|
759
|
+
|
|
760
|
+
```python
|
|
761
|
+
from e6data_python_connector import Connection
|
|
762
|
+
|
|
763
|
+
conn = Connection(
|
|
764
|
+
host=host,
|
|
765
|
+
port=port,
|
|
766
|
+
username=username,
|
|
767
|
+
password=password,
|
|
768
|
+
database=database,
|
|
769
|
+
debug=True # Enable debug logging
|
|
770
|
+
)
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
When `debug=True`, the following features are enabled:
|
|
774
|
+
- Python logging at DEBUG level for all operations
|
|
775
|
+
- Blue-green strategy transition logging
|
|
776
|
+
- Connection lifecycle logging
|
|
777
|
+
- Query execution detailed logging
|
|
778
|
+
|
|
779
|
+
### gRPC Network Tracing
|
|
780
|
+
|
|
781
|
+
For low-level gRPC network debugging (HTTP/2 frames, TCP events), set environment variables **before** running your Python script:
|
|
782
|
+
|
|
783
|
+
```bash
|
|
784
|
+
# Enable gRPC network tracing
|
|
785
|
+
export GRPC_VERBOSITY=DEBUG
|
|
786
|
+
export GRPC_TRACE=client_channel,http2
|
|
787
|
+
|
|
788
|
+
# For comprehensive tracing
|
|
789
|
+
export GRPC_TRACE=api,call_error,channel,client_channel,connectivity_state,http,http2_stream,tcp,transport_security
|
|
790
|
+
|
|
791
|
+
# Run your script
|
|
792
|
+
python your_script.py
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
**Note**: These environment variables must be set before Python starts, as the gRPC C++ core reads them at module import time.
|
|
796
|
+
|
|
797
|
+
### Common Issues and Solutions
|
|
798
|
+
|
|
799
|
+
| Issue | Solution |
|
|
800
|
+
|-------|----------|
|
|
801
|
+
| Connection timeout | Check network connectivity, firewall rules, and ensure port 80/443 is open |
|
|
802
|
+
| Authentication failure | Verify username (email) and access token are correct |
|
|
803
|
+
| 503 Service Unavailable | Cluster may be suspended; enable `auto_resume=True` |
|
|
804
|
+
| 456 Strategy Error | Automatic blue-green failover will handle this |
|
|
805
|
+
| Memory issues with large results | Use `fetchall_buffer()` instead of `fetchall()` |
|
|
806
|
+
| gRPC message size errors | Configure `grpc_options` with appropriate message size limits |
|
|
807
|
+
| fastbinary import error | Install system dependencies (`python3-devel`, `gcc-c++`) or set `require_fastbinary=False` |
|
|
808
|
+
|
|
640
809
|
See [TECH_DOC.md](TECH_DOC.md) for detailed technical documentation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# e6data Python Connector
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
## Introduction
|
|
6
6
|
|
|
@@ -83,8 +83,11 @@ The `Connection` class supports the following parameters:
|
|
|
83
83
|
| `catalog` | str | No | None | Catalog name |
|
|
84
84
|
| `cluster_name` | str | No | None | Name of the cluster for cluster-specific operations |
|
|
85
85
|
| `secure` | bool | No | False | Enable SSL/TLS for secure connections |
|
|
86
|
+
| `ssl_cert` | str/bytes | No | None | Path to CA certificate (PEM) or certificate bytes for HTTPS connections |
|
|
86
87
|
| `auto_resume` | bool | No | True | Automatically resume cluster if suspended |
|
|
87
88
|
| `grpc_options` | dict | No | None | Additional gRPC configuration options |
|
|
89
|
+
| `debug` | bool | No | False | Enable debug logging for troubleshooting |
|
|
90
|
+
| `require_fastbinary` | bool | No | True | Require fastbinary module for Thrift deserialization. Set to False to use pure Python implementation if system dependencies cannot be installed |
|
|
88
91
|
|
|
89
92
|
#### Secure Connection Example
|
|
90
93
|
|
|
@@ -118,6 +121,117 @@ conn = Connection(
|
|
|
118
121
|
)
|
|
119
122
|
```
|
|
120
123
|
|
|
124
|
+
#### HTTPS Connection with HAProxy
|
|
125
|
+
|
|
126
|
+
When connecting through HAProxy with HTTPS, you can provide a custom CA certificate for secure connections. The `ssl_cert` parameter accepts either a file path to a PEM certificate or the certificate content as bytes.
|
|
127
|
+
|
|
128
|
+
**Using a CA certificate file path:**
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
conn = Connection(
|
|
132
|
+
host=host,
|
|
133
|
+
port=443,
|
|
134
|
+
username=username,
|
|
135
|
+
password=password,
|
|
136
|
+
database=database,
|
|
137
|
+
secure=True,
|
|
138
|
+
ssl_cert='/path/to/ca-cert.pem' # Path to your CA certificate
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Reading certificate content as bytes:**
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# Read certificate file and pass as bytes
|
|
146
|
+
with open('/path/to/ca-cert.pem', 'rb') as cert_file:
|
|
147
|
+
cert_data = cert_file.read()
|
|
148
|
+
|
|
149
|
+
conn = Connection(
|
|
150
|
+
host=host,
|
|
151
|
+
port=443,
|
|
152
|
+
username=username,
|
|
153
|
+
password=password,
|
|
154
|
+
database=database,
|
|
155
|
+
secure=True,
|
|
156
|
+
ssl_cert=cert_data # Certificate content as bytes
|
|
157
|
+
)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Using system CA bundle for publicly signed certificates:**
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
# When ssl_cert is None, system default CA bundle is used
|
|
164
|
+
conn = Connection(
|
|
165
|
+
host=host,
|
|
166
|
+
port=443,
|
|
167
|
+
username=username,
|
|
168
|
+
password=password,
|
|
169
|
+
database=database,
|
|
170
|
+
secure=True # Uses system CA bundle by default
|
|
171
|
+
)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Connection pooling with custom CA certificate:**
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
pool = ConnectionPool(
|
|
178
|
+
min_size=2,
|
|
179
|
+
max_size=10,
|
|
180
|
+
host=host,
|
|
181
|
+
port=443,
|
|
182
|
+
username=username,
|
|
183
|
+
password=password,
|
|
184
|
+
database=database,
|
|
185
|
+
secure=True,
|
|
186
|
+
ssl_cert='/path/to/ca-cert.pem' # Custom CA certificate for pool connections
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### Handling Missing System Dependencies
|
|
191
|
+
|
|
192
|
+
The e6data connector uses the `fastbinary` module (from Apache Thrift) for optimal performance when deserializing data. This module requires system-level dependencies (`python3-devel` and `gcc-c++`) to be installed.
|
|
193
|
+
|
|
194
|
+
**Default Behavior (Recommended):**
|
|
195
|
+
By default, the connector requires `fastbinary` to be available. If it's not found, the connection will fail immediately with a clear error message:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
conn = Connection(
|
|
199
|
+
host=host,
|
|
200
|
+
port=port,
|
|
201
|
+
username=username,
|
|
202
|
+
password=password,
|
|
203
|
+
database=database
|
|
204
|
+
)
|
|
205
|
+
# Raises exception if fastbinary is not available
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
**Fallback to Pure Python:**
|
|
209
|
+
If you cannot install system dependencies (e.g., in restricted environments, serverless platforms, or containers without build tools), you can disable the `fastbinary` requirement. The connector will fall back to a pure Python implementation with a performance penalty:
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
conn = Connection(
|
|
213
|
+
host=host,
|
|
214
|
+
port=port,
|
|
215
|
+
username=username,
|
|
216
|
+
password=password,
|
|
217
|
+
database=database,
|
|
218
|
+
require_fastbinary=False # Allow operation without fastbinary
|
|
219
|
+
)
|
|
220
|
+
# Logs warning but continues with pure Python implementation
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**When to use `require_fastbinary=False`:**
|
|
224
|
+
- Running in AWS Lambda or other serverless environments
|
|
225
|
+
- Docker containers built without compilation tools
|
|
226
|
+
- Restricted environments where system packages cannot be installed
|
|
227
|
+
- Development/testing environments where performance is not critical
|
|
228
|
+
|
|
229
|
+
**Performance Impact:**
|
|
230
|
+
- With `fastbinary`: Optimal performance for data deserialization
|
|
231
|
+
- Without `fastbinary` (pure Python): ~2-3x slower deserialization, but otherwise fully functional
|
|
232
|
+
|
|
233
|
+
**Note:** It's strongly recommended to install system dependencies when possible for best performance. The `require_fastbinary=False` option should only be used when system dependencies cannot be installed.
|
|
234
|
+
|
|
121
235
|
### Perform a Queries & Get Results
|
|
122
236
|
|
|
123
237
|
```python
|
|
@@ -598,4 +712,59 @@ conn.close()
|
|
|
598
712
|
- Graceful connection recovery and retry logic
|
|
599
713
|
- Blue-green deployment support with automatic failover
|
|
600
714
|
|
|
715
|
+
## Debugging and Troubleshooting
|
|
716
|
+
|
|
717
|
+
### Enable Debug Mode
|
|
718
|
+
|
|
719
|
+
Enable comprehensive debugging to troubleshoot connection and query issues:
|
|
720
|
+
|
|
721
|
+
```python
|
|
722
|
+
from e6data_python_connector import Connection
|
|
723
|
+
|
|
724
|
+
conn = Connection(
|
|
725
|
+
host=host,
|
|
726
|
+
port=port,
|
|
727
|
+
username=username,
|
|
728
|
+
password=password,
|
|
729
|
+
database=database,
|
|
730
|
+
debug=True # Enable debug logging
|
|
731
|
+
)
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
When `debug=True`, the following features are enabled:
|
|
735
|
+
- Python logging at DEBUG level for all operations
|
|
736
|
+
- Blue-green strategy transition logging
|
|
737
|
+
- Connection lifecycle logging
|
|
738
|
+
- Query execution detailed logging
|
|
739
|
+
|
|
740
|
+
### gRPC Network Tracing
|
|
741
|
+
|
|
742
|
+
For low-level gRPC network debugging (HTTP/2 frames, TCP events), set environment variables **before** running your Python script:
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
# Enable gRPC network tracing
|
|
746
|
+
export GRPC_VERBOSITY=DEBUG
|
|
747
|
+
export GRPC_TRACE=client_channel,http2
|
|
748
|
+
|
|
749
|
+
# For comprehensive tracing
|
|
750
|
+
export GRPC_TRACE=api,call_error,channel,client_channel,connectivity_state,http,http2_stream,tcp,transport_security
|
|
751
|
+
|
|
752
|
+
# Run your script
|
|
753
|
+
python your_script.py
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
**Note**: These environment variables must be set before Python starts, as the gRPC C++ core reads them at module import time.
|
|
757
|
+
|
|
758
|
+
### Common Issues and Solutions
|
|
759
|
+
|
|
760
|
+
| Issue | Solution |
|
|
761
|
+
|-------|----------|
|
|
762
|
+
| Connection timeout | Check network connectivity, firewall rules, and ensure port 80/443 is open |
|
|
763
|
+
| Authentication failure | Verify username (email) and access token are correct |
|
|
764
|
+
| 503 Service Unavailable | Cluster may be suspended; enable `auto_resume=True` |
|
|
765
|
+
| 456 Strategy Error | Automatic blue-green failover will handle this |
|
|
766
|
+
| Memory issues with large results | Use `fetchall_buffer()` instead of `fetchall()` |
|
|
767
|
+
| gRPC message size errors | Configure `grpc_options` with appropriate message size limits |
|
|
768
|
+
| fastbinary import error | Install system dependencies (`python3-devel`, `gcc-c++`) or set `require_fastbinary=False` |
|
|
769
|
+
|
|
601
770
|
See [TECH_DOC.md](TECH_DOC.md) for detailed technical documentation.
|