e6data-python-connector 2.3.10rc7__tar.gz → 2.3.10rc8__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.
Files changed (86) hide show
  1. {e6data_python_connector-2.3.10rc7/e6data_python_connector.egg-info → e6data_python_connector-2.3.10rc8}/PKG-INFO +10 -204
  2. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/README.md +2 -195
  3. e6data_python_connector-2.3.10rc8/e6data_python_connector/__init__.py +3 -0
  4. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/e6data_grpc.py +1 -1
  5. e6data_python_connector-2.3.10rc8/e6data_python_connector/server/e6x_engine_pb2.py +207 -0
  6. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/server/e6x_engine_pb2.pyi +560 -276
  7. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/server/e6x_engine_pb2_grpc.py +807 -282
  8. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8/e6data_python_connector.egg-info}/PKG-INFO +10 -204
  9. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector.egg-info/SOURCES.txt +0 -6
  10. e6data_python_connector-2.3.10rc8/e6data_python_connector.egg-info/requires.txt +8 -0
  11. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/setup.py +8 -9
  12. e6data_python_connector-2.3.10rc7/e6data_python_connector/__init__.py +0 -4
  13. e6data_python_connector-2.3.10rc7/e6data_python_connector/connection_pool.py +0 -495
  14. e6data_python_connector-2.3.10rc7/e6data_python_connector/server/e6x_engine_pb2.py +0 -141
  15. e6data_python_connector-2.3.10rc7/e6data_python_connector.egg-info/requires.txt +0 -8
  16. e6data_python_connector-2.3.10rc7/test/test_connection_pool.py +0 -410
  17. e6data_python_connector-2.3.10rc7/test/test_connection_pool_e2e.py +0 -564
  18. e6data_python_connector-2.3.10rc7/test/test_pool_concurrency_simple.py +0 -573
  19. e6data_python_connector-2.3.10rc7/test/test_pool_threading_multiprocessing.py +0 -679
  20. e6data_python_connector-2.3.10rc7/test/test_simple_connection_pool.py +0 -278
  21. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/LICENSE +0 -0
  22. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/MANIFEST.in +0 -0
  23. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/cluster_manager.py +0 -0
  24. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/cluster_server/__init__.py +0 -0
  25. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/cluster_server/cluster_pb2.py +0 -0
  26. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/cluster_server/cluster_pb2_grpc.py +0 -0
  27. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/common.py +0 -0
  28. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/constants.py +0 -0
  29. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/datainputstream.py +0 -0
  30. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/date_time_utils.py +0 -0
  31. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/dialect.py +0 -0
  32. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/e6x_vector/__init__.py +0 -0
  33. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/e6x_vector/constants.py +0 -0
  34. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/e6x_vector/ttypes.py +0 -0
  35. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/exceptions.py +0 -0
  36. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/server/QueryEngineService.py +0 -0
  37. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/server/__init__.py +0 -0
  38. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/server/constants.py +0 -0
  39. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/server/ttypes.py +0 -0
  40. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/strategy.py +0 -0
  41. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector/typeId.py +0 -0
  42. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector.egg-info/dependency_links.txt +0 -0
  43. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector.egg-info/entry_points.txt +0 -0
  44. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/e6data_python_connector.egg-info/top_level.txt +0 -0
  45. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/pyproject.toml +0 -0
  46. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/setup.cfg +0 -0
  47. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/__init__.py +0 -0
  48. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/analyze_38_nines.py +0 -0
  49. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/analyze_all_cases.py +0 -0
  50. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/analyze_binary.py +0 -0
  51. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/analyze_correct_value.py +0 -0
  52. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/analyze_fields.py +0 -0
  53. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/check_decimal_errors.py +0 -0
  54. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/cleanup_test_files.py +0 -0
  55. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/debug_38_nines.py +0 -0
  56. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/debug_binary.py +0 -0
  57. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/final_test.py +0 -0
  58. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/move_tests.py +0 -0
  59. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/quick_test.py +0 -0
  60. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_38_nines.py +0 -0
  61. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_all_decimal128_cases.py +0 -0
  62. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_cluster_manager_efficiency.py +0 -0
  63. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_cluster_manager_none_strategy.py +0 -0
  64. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_cluster_manager_strategy.py +0 -0
  65. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_comprehensive.py +0 -0
  66. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_current_implementation.py +0 -0
  67. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_decimal128_binary_parsing.py +0 -0
  68. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_decimal128_parsing.py +0 -0
  69. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_fix.py +0 -0
  70. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_improved_parsing.py +0 -0
  71. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_known_case.py +0 -0
  72. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_manual_analysis.py +0 -0
  73. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_mock_server.py +0 -0
  74. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_multiprocessing_fix.py +0 -0
  75. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_new_implementation.py +0 -0
  76. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_specific_binary.py +0 -0
  77. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_strategy.py +0 -0
  78. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_strategy_logic.py +0 -0
  79. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_strategy_persistence_fix.py +0 -0
  80. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_strategy_sharing_fix.py +0 -0
  81. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/test_user_binary_value.py +0 -0
  82. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/tests.py +0 -0
  83. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/tests_grpc.py +0 -0
  84. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/validate_decimal128.py +0 -0
  85. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/test/validate_implementation.py +0 -0
  86. {e6data_python_connector-2.3.10rc7 → e6data_python_connector-2.3.10rc8}/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.10rc7
3
+ Version: 2.3.10rc8
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.
@@ -16,17 +16,16 @@ Classifier: Programming Language :: Python :: 3.9
16
16
  Classifier: Programming Language :: Python :: 3.10
17
17
  Classifier: Programming Language :: Python :: 3.11
18
18
  Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Programming Language :: Python :: 3.13
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
21
  Requires-Dist: sqlalchemy>=1.0.0
23
- Requires-Dist: future>=1.0.0
24
- Requires-Dist: python-dateutil>=2.9.0
25
- Requires-Dist: pycryptodome>=3.19.1
26
- Requires-Dist: pytz>=2024.1
27
- Requires-Dist: thrift>=0.20.0
28
- Requires-Dist: grpcio>=1.65.1
29
- Requires-Dist: grpcio-tools>=1.65.1
22
+ Requires-Dist: future==1.0.0
23
+ Requires-Dist: python-dateutil==2.9.0.post0
24
+ Requires-Dist: pycryptodome==3.19.1
25
+ Requires-Dist: pytz==2024.1
26
+ Requires-Dist: thrift==0.20.0
27
+ Requires-Dist: grpcio==1.65.1
28
+ Requires-Dist: grpcio-tools
30
29
  Dynamic: author
31
30
  Dynamic: author-email
32
31
  Dynamic: classifier
@@ -39,7 +38,7 @@ Dynamic: summary
39
38
 
40
39
  # e6data Python Connector
41
40
 
42
- ![version](https://img.shields.io/badge/version-2.3.10rc7-blue.svg)
41
+ ![version](https://img.shields.io/badge/version-2.3.10rc8-blue.svg)
43
42
 
44
43
  ## Introduction
45
44
 
@@ -76,8 +75,6 @@ Use your e6data Email ID as the username and your access token as the password.
76
75
 
77
76
  ```python
78
77
  from e6data_python_connector import Connection
79
- # For connection pooling (recommended for concurrent operations)
80
- from e6data_python_connector import ConnectionPool
81
78
 
82
79
  username = '<username>' # Your e6data Email ID.
83
80
  password = '<password>' # Access Token generated in the e6data console.
@@ -87,7 +84,6 @@ database = '<database>' # Database to perform the query on.
87
84
  port = 80 # Port of the e6data engine.
88
85
  catalog_name = '<catalog_name>'
89
86
 
90
- # Single connection (for simple, single-threaded use)
91
87
  conn = Connection(
92
88
  host=host,
93
89
  port=port,
@@ -95,17 +91,6 @@ conn = Connection(
95
91
  database=database,
96
92
  password=password
97
93
  )
98
-
99
- # Or use connection pool (for concurrent/multi-threaded use)
100
- pool = ConnectionPool(
101
- min_size=2,
102
- max_size=10,
103
- host=host,
104
- port=port,
105
- username=username,
106
- database=database,
107
- password=password
108
- )
109
94
  ```
110
95
 
111
96
  #### Connection Parameters
@@ -454,187 +439,8 @@ For detailed migration instructions, see the [Migration Guide](docs/zero-downtim
454
439
  - Message size optimization for large queries
455
440
 
456
441
  ### Connection Management
457
-
458
- #### Connection Pooling
459
-
460
- The e6data Python connector now includes a built-in connection pool for efficient connection management and reuse across multiple threads. The `ConnectionPool` class provides:
461
-
462
- - **Thread-safe connection reuse**: Each thread automatically reuses its assigned connection
463
- - **Automatic lifecycle management**: Handles connection creation, health checks, and cleanup
464
- - **Overflow connections**: Creates temporary connections when pool is exhausted
465
- - **Connection health monitoring**: Automatic detection and replacement of broken connections
466
- - **Statistics tracking**: Monitor pool usage and performance
467
-
468
- ##### Basic Connection Pool Usage
469
-
470
- ```python
471
- from e6data_python_connector import ConnectionPool
472
-
473
- # Create a connection pool
474
- pool = ConnectionPool(
475
- min_size=2, # Minimum connections to maintain
476
- max_size=10, # Maximum connections in pool
477
- max_overflow=5, # Additional temporary connections allowed
478
- timeout=30.0, # Timeout for getting connection (seconds)
479
- recycle=3600, # Maximum age before recycling (seconds)
480
- debug=False, # Enable debug logging
481
- pre_ping=True, # Check connection health before use
482
- # Connection parameters
483
- host=host,
484
- port=port,
485
- username=username,
486
- password=password,
487
- database=database,
488
- catalog=catalog_name,
489
- cluster_name=cluster_name,
490
- secure=True
491
- )
492
-
493
- # Get connection and execute query
494
- conn = pool.get_connection()
495
- cursor = conn.cursor()
496
- cursor.execute("SELECT * FROM table")
497
- results = cursor.fetchall()
498
-
499
- # Return connection to pool (important!)
500
- pool.return_connection(conn)
501
-
502
- # Clean up when done
503
- pool.close_all()
504
- ```
505
-
506
- ##### Using Context Manager (Recommended)
507
-
508
- The context manager pattern ensures connections are automatically returned to the pool:
509
-
510
- ```python
511
- from e6data_python_connector import ConnectionPool
512
-
513
- pool = ConnectionPool(
514
- min_size=2,
515
- max_size=10,
516
- host=host,
517
- port=port,
518
- username=username,
519
- password=password,
520
- database=database
521
- )
522
-
523
- # Connection automatically returned to pool after use
524
- with pool.get_connection_context() as conn:
525
- cursor = conn.cursor()
526
- cursor.execute("SELECT * FROM table")
527
- results = cursor.fetchall()
528
- print(results)
529
- ```
530
-
531
- ##### Concurrent Query Execution
532
-
533
- Connection pooling is especially beneficial for concurrent query execution:
534
-
535
- ```python
536
- import concurrent.futures
537
- from e6data_python_connector import ConnectionPool
538
-
539
- def execute_query(pool, query_id, query):
540
- """Execute a query using a pooled connection."""
541
- # Each thread will reuse its assigned connection
542
- conn = pool.get_connection()
543
- try:
544
- cursor = conn.cursor()
545
- cursor.execute(query)
546
- results = cursor.fetchall()
547
- return f"Query {query_id}: {len(results)} rows"
548
- finally:
549
- pool.return_connection(conn)
550
-
551
- # Create pool
552
- pool = ConnectionPool(
553
- min_size=3,
554
- max_size=10,
555
- host=host,
556
- port=port,
557
- username=username,
558
- password=password,
559
- database=database
560
- )
561
-
562
- # Execute multiple queries concurrently
563
- queries = [
564
- "SELECT COUNT(*) FROM table1",
565
- "SELECT AVG(value) FROM table2",
566
- "SELECT MAX(date) FROM table3"
567
- ]
568
-
569
- with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
570
- futures = [
571
- executor.submit(execute_query, pool, i, query)
572
- for i, query in enumerate(queries)
573
- ]
574
-
575
- for future in concurrent.futures.as_completed(futures):
576
- print(future.result())
577
-
578
- # Clean up
579
- pool.close_all()
580
- ```
581
-
582
- ##### Connection Pool Configuration
583
-
584
- | Parameter | Type | Default | Description |
585
- |-----------|------|---------|-------------|
586
- | `min_size` | int | 2 | Minimum number of connections to maintain |
587
- | `max_size` | int | 10 | Maximum number of connections in pool |
588
- | `max_overflow` | int | 5 | Additional temporary connections allowed |
589
- | `timeout` | float | 30.0 | Timeout for getting connection (seconds) |
590
- | `recycle` | int | 3600 | Maximum connection age before recycling (seconds) |
591
- | `debug` | bool | False | Enable debug logging for pool operations |
592
- | `pre_ping` | bool | True | Check connection health before returning from pool |
593
-
594
- ##### Monitoring Pool Statistics
595
-
596
- ```python
597
- # Get pool statistics
598
- stats = pool.get_statistics()
599
- print(f"Active connections: {stats['active_connections']}")
600
- print(f"Idle connections: {stats['idle_connections']}")
601
- print(f"Total requests: {stats['total_requests']}")
602
- print(f"Failed connections: {stats['failed_connections']}")
603
- ```
604
-
605
- ##### When to Use Connection Pooling
606
-
607
- Connection pooling is recommended when:
608
- - Executing multiple queries concurrently
609
- - Building web applications or APIs
610
- - Running batch processing jobs
611
- - Reducing connection overhead
612
- - Improving application performance
613
-
614
- ##### Direct Connection Usage (Without Pool)
615
-
616
- For simple, single-threaded applications, you can still use direct connections:
617
-
618
- ```python
619
- from e6data_python_connector import Connection
620
-
621
- conn = Connection(
622
- host=host,
623
- port=port,
624
- username=username,
625
- password=password,
626
- database=database
627
- )
628
-
629
- cursor = conn.cursor()
630
- cursor.execute("SELECT * FROM table")
631
- results = cursor.fetchall()
632
- conn.close()
633
- ```
634
-
635
- #### Additional Connection Management Features
442
+ - Enable connection pooling for better resource utilization
636
443
  - Automatic connection health monitoring
637
444
  - Graceful connection recovery and retry logic
638
- - Blue-green deployment support with automatic failover
639
445
 
640
446
  See [TECH_DOC.md](TECH_DOC.md) for detailed technical documentation.
@@ -1,6 +1,6 @@
1
1
  # e6data Python Connector
2
2
 
3
- ![version](https://img.shields.io/badge/version-2.3.10rc7-blue.svg)
3
+ ![version](https://img.shields.io/badge/version-2.3.10rc8-blue.svg)
4
4
 
5
5
  ## Introduction
6
6
 
@@ -37,8 +37,6 @@ Use your e6data Email ID as the username and your access token as the password.
37
37
 
38
38
  ```python
39
39
  from e6data_python_connector import Connection
40
- # For connection pooling (recommended for concurrent operations)
41
- from e6data_python_connector import ConnectionPool
42
40
 
43
41
  username = '<username>' # Your e6data Email ID.
44
42
  password = '<password>' # Access Token generated in the e6data console.
@@ -48,7 +46,6 @@ database = '<database>' # Database to perform the query on.
48
46
  port = 80 # Port of the e6data engine.
49
47
  catalog_name = '<catalog_name>'
50
48
 
51
- # Single connection (for simple, single-threaded use)
52
49
  conn = Connection(
53
50
  host=host,
54
51
  port=port,
@@ -56,17 +53,6 @@ conn = Connection(
56
53
  database=database,
57
54
  password=password
58
55
  )
59
-
60
- # Or use connection pool (for concurrent/multi-threaded use)
61
- pool = ConnectionPool(
62
- min_size=2,
63
- max_size=10,
64
- host=host,
65
- port=port,
66
- username=username,
67
- database=database,
68
- password=password
69
- )
70
56
  ```
71
57
 
72
58
  #### Connection Parameters
@@ -415,187 +401,8 @@ For detailed migration instructions, see the [Migration Guide](docs/zero-downtim
415
401
  - Message size optimization for large queries
416
402
 
417
403
  ### Connection Management
418
-
419
- #### Connection Pooling
420
-
421
- The e6data Python connector now includes a built-in connection pool for efficient connection management and reuse across multiple threads. The `ConnectionPool` class provides:
422
-
423
- - **Thread-safe connection reuse**: Each thread automatically reuses its assigned connection
424
- - **Automatic lifecycle management**: Handles connection creation, health checks, and cleanup
425
- - **Overflow connections**: Creates temporary connections when pool is exhausted
426
- - **Connection health monitoring**: Automatic detection and replacement of broken connections
427
- - **Statistics tracking**: Monitor pool usage and performance
428
-
429
- ##### Basic Connection Pool Usage
430
-
431
- ```python
432
- from e6data_python_connector import ConnectionPool
433
-
434
- # Create a connection pool
435
- pool = ConnectionPool(
436
- min_size=2, # Minimum connections to maintain
437
- max_size=10, # Maximum connections in pool
438
- max_overflow=5, # Additional temporary connections allowed
439
- timeout=30.0, # Timeout for getting connection (seconds)
440
- recycle=3600, # Maximum age before recycling (seconds)
441
- debug=False, # Enable debug logging
442
- pre_ping=True, # Check connection health before use
443
- # Connection parameters
444
- host=host,
445
- port=port,
446
- username=username,
447
- password=password,
448
- database=database,
449
- catalog=catalog_name,
450
- cluster_name=cluster_name,
451
- secure=True
452
- )
453
-
454
- # Get connection and execute query
455
- conn = pool.get_connection()
456
- cursor = conn.cursor()
457
- cursor.execute("SELECT * FROM table")
458
- results = cursor.fetchall()
459
-
460
- # Return connection to pool (important!)
461
- pool.return_connection(conn)
462
-
463
- # Clean up when done
464
- pool.close_all()
465
- ```
466
-
467
- ##### Using Context Manager (Recommended)
468
-
469
- The context manager pattern ensures connections are automatically returned to the pool:
470
-
471
- ```python
472
- from e6data_python_connector import ConnectionPool
473
-
474
- pool = ConnectionPool(
475
- min_size=2,
476
- max_size=10,
477
- host=host,
478
- port=port,
479
- username=username,
480
- password=password,
481
- database=database
482
- )
483
-
484
- # Connection automatically returned to pool after use
485
- with pool.get_connection_context() as conn:
486
- cursor = conn.cursor()
487
- cursor.execute("SELECT * FROM table")
488
- results = cursor.fetchall()
489
- print(results)
490
- ```
491
-
492
- ##### Concurrent Query Execution
493
-
494
- Connection pooling is especially beneficial for concurrent query execution:
495
-
496
- ```python
497
- import concurrent.futures
498
- from e6data_python_connector import ConnectionPool
499
-
500
- def execute_query(pool, query_id, query):
501
- """Execute a query using a pooled connection."""
502
- # Each thread will reuse its assigned connection
503
- conn = pool.get_connection()
504
- try:
505
- cursor = conn.cursor()
506
- cursor.execute(query)
507
- results = cursor.fetchall()
508
- return f"Query {query_id}: {len(results)} rows"
509
- finally:
510
- pool.return_connection(conn)
511
-
512
- # Create pool
513
- pool = ConnectionPool(
514
- min_size=3,
515
- max_size=10,
516
- host=host,
517
- port=port,
518
- username=username,
519
- password=password,
520
- database=database
521
- )
522
-
523
- # Execute multiple queries concurrently
524
- queries = [
525
- "SELECT COUNT(*) FROM table1",
526
- "SELECT AVG(value) FROM table2",
527
- "SELECT MAX(date) FROM table3"
528
- ]
529
-
530
- with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
531
- futures = [
532
- executor.submit(execute_query, pool, i, query)
533
- for i, query in enumerate(queries)
534
- ]
535
-
536
- for future in concurrent.futures.as_completed(futures):
537
- print(future.result())
538
-
539
- # Clean up
540
- pool.close_all()
541
- ```
542
-
543
- ##### Connection Pool Configuration
544
-
545
- | Parameter | Type | Default | Description |
546
- |-----------|------|---------|-------------|
547
- | `min_size` | int | 2 | Minimum number of connections to maintain |
548
- | `max_size` | int | 10 | Maximum number of connections in pool |
549
- | `max_overflow` | int | 5 | Additional temporary connections allowed |
550
- | `timeout` | float | 30.0 | Timeout for getting connection (seconds) |
551
- | `recycle` | int | 3600 | Maximum connection age before recycling (seconds) |
552
- | `debug` | bool | False | Enable debug logging for pool operations |
553
- | `pre_ping` | bool | True | Check connection health before returning from pool |
554
-
555
- ##### Monitoring Pool Statistics
556
-
557
- ```python
558
- # Get pool statistics
559
- stats = pool.get_statistics()
560
- print(f"Active connections: {stats['active_connections']}")
561
- print(f"Idle connections: {stats['idle_connections']}")
562
- print(f"Total requests: {stats['total_requests']}")
563
- print(f"Failed connections: {stats['failed_connections']}")
564
- ```
565
-
566
- ##### When to Use Connection Pooling
567
-
568
- Connection pooling is recommended when:
569
- - Executing multiple queries concurrently
570
- - Building web applications or APIs
571
- - Running batch processing jobs
572
- - Reducing connection overhead
573
- - Improving application performance
574
-
575
- ##### Direct Connection Usage (Without Pool)
576
-
577
- For simple, single-threaded applications, you can still use direct connections:
578
-
579
- ```python
580
- from e6data_python_connector import Connection
581
-
582
- conn = Connection(
583
- host=host,
584
- port=port,
585
- username=username,
586
- password=password,
587
- database=database
588
- )
589
-
590
- cursor = conn.cursor()
591
- cursor.execute("SELECT * FROM table")
592
- results = cursor.fetchall()
593
- conn.close()
594
- ```
595
-
596
- #### Additional Connection Management Features
404
+ - Enable connection pooling for better resource utilization
597
405
  - Automatic connection health monitoring
598
406
  - Graceful connection recovery and retry logic
599
- - Blue-green deployment support with automatic failover
600
407
 
601
408
  See [TECH_DOC.md](TECH_DOC.md) for detailed technical documentation.
@@ -0,0 +1,3 @@
1
+ from e6data_python_connector.e6data_grpc import Connection, Cursor
2
+
3
+ __all__ = ['Connection', 'Cursor']
@@ -370,7 +370,7 @@ class Connection(object):
370
370
  self.__username = username
371
371
  self.__password = password
372
372
  self.database = database
373
- self.cluster_name = cluster_name.lower() if cluster_name else cluster_name
373
+ self.cluster_name = cluster_name
374
374
  self._session_id = None
375
375
  self._host = host
376
376
  self._port = port