fastmssql 0.3.0__cp310-cp310-macosx_11_0_arm64.whl → 0.3.3__cp310-cp310-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fastmssql might be problematic. Click here for more details.

@@ -1,803 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: fastmssql
3
- Version: 0.3.0
4
- Classifier: Development Status :: 4 - Beta
5
- Classifier: Intended Audience :: Developers
6
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
7
- Classifier: Programming Language :: Python :: 3
8
- Classifier: Programming Language :: Python :: 3.8
9
- Classifier: Programming Language :: Python :: 3.9
10
- Classifier: Programming Language :: Python :: 3.10
11
- Classifier: Programming Language :: Python :: 3.11
12
- Classifier: Programming Language :: Python :: 3.12
13
- Classifier: Programming Language :: Python :: 3.13
14
- Classifier: Programming Language :: Rust
15
- Classifier: Topic :: Database
16
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
- Requires-Dist: pytest>=7.0 ; extra == 'dev'
18
- Requires-Dist: pytest-asyncio>=0.21 ; extra == 'dev'
19
- Requires-Dist: psutil>=5.9.0 ; extra == 'dev'
20
- Provides-Extra: dev
21
- License-File: LICENSE
22
- Summary: A high-performance Python library for Microsoft SQL Server using Rust and Tiberius
23
- Author-email: Riveranda <riverb514@gmail.com>
24
- License: GPL-3.0-or-later OR Commercial
25
- Requires-Python: >=3.8
26
- Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
27
- Project-URL: Homepage, https://github.com/Rivendael/pymssql-rs
28
-
29
-
30
- # Fastmssql ⚡
31
-
32
- A Python library for Microsoft SQL Server built with Rust using the [Tiberius](https://github.com/prisma/tiberius) driver, [PyO3](https://github.com/PyO3/pyo3), and [bb8](https://github.com/djc/bb8) connection pooling.
33
-
34
- [![Language](https://img.shields.io/badge/Language-Rust_Backend-red)](https://github.com/Rivendael/pymssql-rs)
35
- [![Async](https://img.shields.io/badge/Async-Native_Tokio-blue)](https://github.com/Rivendael/pymssql-rs)
36
- [![Performance](https://img.shields.io/badge/Performance-17%2C800%2B_RPS-brightgreen)](https://github.com/Rivendael/pymssql-rs)
37
-
38
- ## Features
39
-
40
- - **High Performance**: Exceptional throughput with 17,800+ RPS capability
41
- - **Rust-Powered Backend**: Built with Rust for memory safety and reliability
42
- - **No ODBC Required**: Direct native SQL Server connection without ODBC drivers
43
- - **Connection Pooling**: Intelligent bb8-based connection pooling (default: 75 max, 25 min idle)
44
- - **Async-Only Design**: Built on Tokio with clean async/await API
45
- - **Context Managers**: Automatic resource management with `async with`
46
- - **Type Safety**: Strong typing with automatic Python type conversion
47
- - **Thread Safety**: Support for concurrent operations
48
- - **Cross-Platform**: Works on Windows, macOS, and Linux
49
- - **Simple API**: Clean, intuitive async-only interface with separate `query()` and `execute()` methods
50
-
51
- ## Key API Methods
52
-
53
- FastMSSQL provides two distinct methods for database operations:
54
-
55
- - **`query()`** - For SELECT statements that return rows
56
- - **`execute()`** - For INSERT/UPDATE/DELETE statements that return affected row count
57
-
58
- ```python
59
- # Use query() for SELECT statements
60
- result = await conn.query("SELECT * FROM users WHERE age > @P1", [25])
61
- rows = result.rows()
62
-
63
- # Use execute() for data modification
64
- affected = await conn.execute("INSERT INTO users (name) VALUES (@P1)", ["John"])
65
- ```
66
-
67
- ## Performance Highlights
68
-
69
- Fastmssql delivers exceptional database performance through Rust-powered architecture:
70
-
71
- - **Outstanding Throughput**: Up to **17,800+ RPS** with multiple connection pattern
72
- - **High Performance**: **5,000+ RPS** with single connection (default usage)
73
- - **Low Latency**: ~2ms average query latency under high load
74
- - **Scalable Architecture**: Linear scaling with multiple connection objects
75
- - **Production Ready**: Stable API with comprehensive error handling
76
- - **Connection Pooling**: Efficient resource management with configurable pools
77
- - **Type Conversion**: Automatic conversion between SQL Server and Python types
78
- - **SSL/TLS Support**: Secure connections with flexible encryption options
79
-
80
- ### Performance Benchmarks
81
-
82
- | Pattern | RPS | Configuration | Use Case |
83
- |---------|-----|---------------|----------|
84
- | Single Connection (Default) | **5,000+** | Default pool (75/25) | Standard applications |
85
- | Multiple Connections | **17,800+** | 50 workers, high_throughput() | High-concurrency scenarios |
86
- | Conservative Load | 3,500+ | Shared connection | Traditional pooling |
87
-
88
- **Benchmark Environment:**
89
- - Database: SQL Server (local instance)
90
- - Query: `SELECT 1` (minimal overhead)
91
- - Test Duration: 15-30 seconds per test
92
- - Hardware: Modern development machine
93
-
94
- **Key Performance Insights:**
95
- 1. **Multiple Connection Objects**: Creating separate `Connection()` objects eliminates serialization bottlenecks
96
- 2. **Pool Configuration**: Use `PoolConfig.high_throughput()` for demanding workloads
97
- 3. **Optimal Worker Count**: 30-50 concurrent workers provides best throughput
98
- 4. **Tokio Optimization**: Aggressive threading configuration maximizes async performance
99
-
100
- ## Installation
101
-
102
- ### From PyPI (Recommended)
103
-
104
- Install fastmssql using pip:
105
-
106
- ```bash
107
- pip install fastmssql
108
- ```
109
-
110
- ### Prerequisites
111
-
112
- - Python 3.8 to 3.13
113
- - Microsoft SQL Server (any recent version)
114
-
115
- ### From Source (Development)
116
- Ensure you have Docker, Rust, and Python installed.
117
- If you want to build from source or contribute to development:
118
-
119
- 1. Clone the repository:
120
- ```bash
121
- git clone <your-repo-url>
122
- cd mssql-python-rust
123
- ```
124
-
125
- 2. Run the setup script
126
- ```
127
- ./setup.sh
128
- ```
129
-
130
- ## Quick Start
131
-
132
- ### Basic Async Usage (Recommended)
133
-
134
- ```python
135
- import asyncio
136
- from fastmssql import Connection
137
-
138
- async def main():
139
- # Connect to SQL Server using async context manager
140
- connection_string = "Server=localhost;Database=master;User Id=myuser;Password=mypass"
141
-
142
- # Automatic connection pool management
143
- async with Connection(connection_string) as conn:
144
- # Use query() for SELECT statements that return rows
145
- result = await conn.query("SELECT @@VERSION as version")
146
- rows = result.rows()
147
- for row in rows:
148
- print(row['version'])
149
-
150
- # Pool statistics
151
- stats = conn.pool_stats()
152
- print(f"Pool: {stats['active_connections']}/{stats['connections']} connections active")
153
-
154
- asyncio.run(main())
155
- ```
156
-
157
- ### Connection Methods
158
-
159
- The library supports two ways to connect to SQL Server:
160
-
161
- #### 1. Connection String (Traditional)
162
-
163
- ```python
164
- import asyncio
165
- from fastmssql import Connection
166
-
167
- async def main():
168
- # Traditional connection string approach
169
- connection_string = "Server=localhost;Database=master;User Id=myuser;Password=mypass"
170
-
171
- async with Connection(connection_string=connection_string) as conn:
172
- # Use query() for SELECT statements that return rows
173
- result = await conn.query("SELECT @@VERSION as version")
174
- rows = result.rows()
175
- for row in rows:
176
- print(row['version'])
177
-
178
- asyncio.run(main())
179
- ```
180
-
181
- #### 2. Individual Parameters
182
-
183
- ```python
184
- import asyncio
185
- from fastmssql import Connection
186
-
187
- async def main():
188
- # Using individual connection parameters
189
-
190
- # SQL Server Authentication
191
- async with Connection(
192
- server="localhost",
193
- database="master",
194
- username="myuser",
195
- password="mypassword"
196
- ) as conn:
197
- # Use query() for SELECT statements that return rows
198
- result = await conn.query("SELECT SUSER_NAME() as login")
199
- rows = result.rows()
200
- for row in rows:
201
- print(f"Logged in as: {row['login']}")
202
-
203
- asyncio.run(main())
204
- ```
205
-
206
- ### Performance Patterns
207
-
208
- For maximum performance in high-concurrency scenarios, create multiple Connection objects:
209
-
210
- ```python
211
- import asyncio
212
- from fastmssql import Connection, PoolConfig
213
-
214
- async def high_performance_pattern():
215
- """Optimal pattern for maximum throughput."""
216
- connection_string = "Server=localhost;Database=master;User Id=myuser;Password=mypass"
217
- config = PoolConfig.high_throughput() # Optimized settings
218
-
219
- async def worker():
220
- # Each worker gets its own Connection object for maximum throughput
221
- async with Connection(connection_string, pool_config=config) as conn:
222
- for _ in range(1000):
223
- # Use query() for SELECT statements that return rows
224
- result = await conn.query("SELECT data FROM my_table WHERE id = @P1", [123])
225
- rows = result.rows()
226
- # Process results...
227
-
228
- # Launch multiple workers - each with their own connection
229
- workers = [asyncio.create_task(worker()) for _ in range(50)]
230
- await asyncio.gather(*workers)
231
-
232
- # This pattern can achieve 17,800+ RPS
233
-
234
- asyncio.run(high_performance_pattern())
235
- ```
236
-
237
- **Key Performance Insight**: While a single Connection object provides excellent performance (5,000+ RPS),
238
- creating multiple Connection objects eliminates serialization bottlenecks and can achieve 17,800+ RPS
239
- for maximum throughput scenarios.
240
-
241
- ### Connection Pool Configuration
242
-
243
- Configure the connection pool for your specific needs:
244
-
245
- ```python
246
- import asyncio
247
- from fastmssql import Connection, PoolConfig
248
-
249
- async def main():
250
- # Custom pool configuration
251
- pool_config = PoolConfig(
252
- max_size=20, # Maximum connections in pool
253
- min_idle=5, # Minimum idle connections
254
- max_lifetime_secs=3600, # Connection max lifetime (1 hour)
255
- idle_timeout_secs=600, # Idle connection timeout (10 min)
256
- connection_timeout_secs=30 # Max wait time for connection
257
- )
258
-
259
- async with Connection(connection_string, pool_config) as conn:
260
- # Use query() for SELECT statements that return rows
261
- result = await conn.query("SELECT * FROM users")
262
- rows = result.rows()
263
- for row in rows:
264
- print(f"User: {row['name']}")
265
-
266
- # Predefined configurations for different scenarios
267
- high_throughput_config = PoolConfig.high_throughput() # 100 connections, optimized for high RPS
268
- maximum_performance = PoolConfig.maximum_performance() # 150 connections, optimized for peak load
269
- low_resource_config = PoolConfig.low_resource() # 3 connections, minimal resources
270
- dev_config = PoolConfig.development() # 5 connections, shorter timeouts
271
-
272
- # Default configuration is optimized for high performance
273
- # Default: max_size=75, min_idle=25 - ready for production workloads
274
-
275
- # For maximum throughput, use multiple Connection objects:
276
- async def high_perf_worker():
277
- async with Connection(connection_string, maximum_performance) as conn:
278
- # Use query() for SELECT statements that return rows
279
- result = await conn.query("SELECT * FROM fast_table")
280
- return result.rows()
281
-
282
- # Each worker gets its own connection for optimal performance
283
- tasks = [asyncio.create_task(high_perf_worker()) for _ in range(50)]
284
- results = await asyncio.gather(*tasks)
285
-
286
- asyncio.run(main())
287
- ```
288
-
289
-
290
-
291
- ### Connection Strings
292
-
293
- The library supports standard SQL Server connection string formats:
294
-
295
- ```python
296
- # SQL Server Authentication
297
- conn_str = "Server=localhost;Database=MyDB;User Id=sa;Password=MyPassword"
298
-
299
- # With specific port
300
- conn_str = "Server=localhost,1433;Database=MyDB;User Id=myuser;Password=mypass"
301
-
302
- # Azure SQL Database
303
- conn_str = "Server=tcp:myserver.database.windows.net,1433;Database=MyDB;User Id=myuser;Password=mypass;Encrypt=true"
304
- ```
305
-
306
- ### Working with Data
307
-
308
- ```python
309
- import asyncio
310
- from fastmssql import Connection
311
-
312
- async def main():
313
- async with Connection(connection_string) as conn:
314
- # === SELECT QUERIES - Use query() method (returns rows) ===
315
- result = await conn.query("SELECT id, name, email FROM users WHERE active = 1")
316
- rows = result.rows()
317
-
318
- # Iterate through results
319
- for row in rows:
320
- print(f"User {row['id']}: {row['name']} ({row['email']})")
321
-
322
- # === DATA MODIFICATION - Use execute() method (returns affected row count) ===
323
- # INSERT operation
324
- rows_affected = await conn.execute(
325
- "INSERT INTO users (name, email, active) VALUES (@P1, @P2, @P3)",
326
- ["John Doe", "john@example.com", 1]
327
- )
328
- print(f"Inserted {rows_affected} row(s)")
329
-
330
- # UPDATE operation
331
- rows_affected = await conn.execute(
332
- "UPDATE users SET last_login = GETDATE() WHERE id = @P1",
333
- [123]
334
- )
335
- print(f"Updated {rows_affected} row(s)")
336
-
337
- # DELETE operation
338
- rows_affected = await conn.execute(
339
- "DELETE FROM users WHERE active = 0 AND last_login < DATEADD(year, -1, GETDATE())"
340
- )
341
- print(f"Deleted {rows_affected} inactive users")
342
-
343
- # === WORKING WITH DIFFERENT DATA TYPES ===
344
- result = await conn.query("""
345
- SELECT
346
- 42 as int_value,
347
- 3.14159 as float_value,
348
- 'Hello World' as string_value,
349
- GETDATE() as datetime_value,
350
- CAST(1 as BIT) as bool_value,
351
- NULL as null_value
352
- """)
353
-
354
- rows = result.rows()
355
- if rows:
356
- row = rows[0]
357
- for column_name, value in row.items():
358
- print(f"{column_name}: {value} (type: {type(value).__name__})")
359
-
360
- asyncio.run(main())
361
- ```
362
-
363
- ## Usage
364
-
365
- ### Asynchronous Usage with Connection Pooling
366
-
367
- Full async/await support with automatic connection pool management:
368
-
369
- ```python
370
- import asyncio
371
- from fastmssql import Connection
372
-
373
- async def main():
374
- connection_string = "Server=localhost;Database=test;Integrated Security=true"
375
-
376
- # Async context manager with automatic pool management
377
- async with Connection(connection_string) as conn:
378
- # Use query() for SELECT statements that return rows
379
- result = await conn.query("SELECT name FROM sys.databases")
380
- rows = result.rows()
381
- for row in rows:
382
- print(row['name'])
383
-
384
- # Pool statistics
385
- stats = conn.pool_stats()
386
- print(f"Pool: {stats['active_connections']}/{stats['connections']} connections active")
387
-
388
- # High-performance concurrent operations
389
- async def fetch_user_data(user_id):
390
- async with Connection(connection_string) as conn:
391
- # Use query() for SELECT statements that return rows
392
- result = await conn.query(f"SELECT * FROM users WHERE id = {user_id}")
393
- return result.rows()
394
-
395
- # Execute multiple queries concurrently using the connection pool
396
- user_ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
397
- tasks = [fetch_user_data(uid) for uid in user_ids]
398
- results = await asyncio.gather(*tasks) # bb8 pool handles concurrent connections efficiently
399
-
400
- for user_data in results:
401
- if user_data:
402
- print(f"User: {user_data[0]['name']}")
403
-
404
- asyncio.run(main())
405
- ```
406
-
407
- ## Development
408
-
409
- ### Building from Source
410
-
411
- ```bash
412
- # Install development dependencies
413
- pip install maturin pytest pytest-asyncio black ruff
414
-
415
- # Build in development mode
416
- maturin develop
417
-
418
- # Run tests
419
- python -m pytest tests/
420
-
421
- # Format code
422
- black python/
423
- ruff check python/
424
- ```
425
-
426
- ### Project Structure
427
-
428
- ```
429
- mssql-python-rust/
430
- ├── src/ # Rust source code
431
- │ ├── lib.rs # Main library entry point
432
- │ ├── connection.rs # Connection handling
433
- │ ├── query.rs # Query execution
434
- │ └── types.rs # Type definitions
435
- ├── python/ # Python source code
436
- │ ├── __init__.py # Main Python module
437
- │ ├── mssql.py # High-level API
438
- │ └── types.py # Python type definitions
439
- ├── examples/ # Usage examples
440
- ├── tests/ # Test files
441
- ├── Cargo.toml # Rust dependencies
442
- ├── pyproject.toml # Python project configuration
443
- └── README.md # This file
444
- ```
445
-
446
- ### Testing
447
-
448
- Run the examples to test your installation:
449
-
450
- ```bash
451
- # Basic functionality
452
- python examples/basic_usage.py
453
-
454
- # Advanced features
455
- python examples/advanced_usage.py
456
- ```
457
-
458
- ## API Reference
459
-
460
- ### Query vs Execute Methods
461
-
462
- FastMSSQL provides two distinct methods for database operations:
463
-
464
- - **`query()`** - For SELECT statements that return rows
465
- - Returns a `QueryResult` object with a `rows()` method
466
- - Use for retrieving data from the database
467
-
468
- - **`execute()`** - For INSERT, UPDATE, DELETE statements
469
- - Returns the number of affected rows as an integer
470
- - Use for modifying data in the database
471
-
472
- **SQL Server Parameter Syntax**: Use positional parameters `@P1`, `@P2`, `@P3`, etc.
473
-
474
- ```python
475
- # SELECT queries - use query()
476
- result = await conn.query("SELECT * FROM users WHERE age > @P1 AND city = @P2", [25, "New York"])
477
- rows = result.rows()
478
-
479
- # INSERT/UPDATE/DELETE - use execute()
480
- affected = await conn.execute("INSERT INTO users (name, email) VALUES (@P1, @P2)", ["John", "john@example.com"])
481
- ```
482
-
483
- ### Core Classes
484
-
485
- #### `Connection`
486
- Main connection class with bb8 connection pool management.
487
-
488
- **Constructor:**
489
- ```python
490
- Connection(connection_string: str, pool_config: Optional[PoolConfig] = None)
491
- ```
492
-
493
- **Context Manager Support:**
494
- ```python
495
- # Asynchronous (recommended)
496
- async with Connection(conn_str) as conn:
497
- # Use query() for SELECT statements
498
- result = await conn.query("SELECT * FROM table")
499
- rows = result.rows()
500
-
501
- # Use execute() for INSERT/UPDATE/DELETE statements
502
- affected = await conn.execute("INSERT INTO table (col) VALUES (@P1)", ["value"])
503
- ```
504
- ```
505
-
506
- **Methods:**
507
- - `query(sql: str, params: Optional[List] = None) -> QueryResult` - Execute SELECT queries that return rows
508
- - `execute(sql: str, params: Optional[List] = None) -> int` - Execute INSERT/UPDATE/DELETE statements, returns affected row count
509
- - `pool_stats() -> dict` - Get connection pool statistics
510
- - `disconnect()` - Close the connection pool
511
- - `is_connected() -> bool` - Check if pool is active
512
-
513
- **Method Details:**
514
-
515
- `query()` - For SELECT statements that return data:
516
- ```python
517
- # Returns a QueryResult object with rows() method
518
- result = await conn.query("SELECT * FROM users WHERE age > @P1", [21])
519
- rows = result.rows()
520
- for row in rows:
521
- print(row['name'])
522
- ```
523
-
524
- `execute()` - For INSERT/UPDATE/DELETE statements:
525
- ```python
526
- # Returns the number of affected rows
527
- affected = await conn.execute("INSERT INTO users (name) VALUES (@P1)", ["John"])
528
- print(f"Inserted {affected} row(s)")
529
-
530
- affected = await conn.execute("UPDATE users SET age = @P1 WHERE name = @P2", [25, "John"])
531
- print(f"Updated {affected} row(s)")
532
- ```
533
-
534
- **Pool Statistics:**
535
- ```python
536
- stats = conn.pool_stats()
537
- # Returns: {
538
- # 'connections': 10, # Total connections in pool
539
- # 'active_connections': 3, # Currently active connections
540
- # 'idle_connections': 7 # Available idle connections
541
- # }
542
- ```
543
-
544
- #### `PoolConfig`
545
- Configuration class for bb8 connection pool settings.
546
-
547
- **Constructor:**
548
- ```python
549
- PoolConfig(
550
- max_size: int = 10, # Maximum connections in pool
551
- min_idle: int = 0, # Minimum idle connections
552
- max_lifetime_secs: Optional[int] = None, # Connection max lifetime
553
- idle_timeout_secs: Optional[int] = None, # Idle connection timeout
554
- connection_timeout_secs: int = 30 # Max wait time for connection
555
- )
556
- ```
557
-
558
- **Predefined Configurations:**
559
- ```python
560
- # High throughput applications (web servers, APIs)
561
- config = PoolConfig.high_throughput() # 20 connections, optimized settings
562
-
563
- # Low resource environments (embedded, containers)
564
- config = PoolConfig.low_resource() # 3 connections, minimal overhead
565
-
566
- # Development environments
567
- config = PoolConfig.development() # 5 connections, shorter timeouts
568
- ```
569
-
570
- #### `Row`
571
- Represents a database row with column access.
572
-
573
- **Methods:**
574
- - `get(column: str) -> Value` - Get value by column name
575
- - `get_by_index(index: int) -> Value` - Get value by column index
576
- - `columns() -> List[str]` - Get column names
577
- - `values() -> List[Value]` - Get all values
578
- - `to_dict() -> dict` - Convert to dictionary
579
-
580
- ### Module Functions
581
-
582
- #### Connection Management
583
- ```python
584
- # Create connection with connection pooling
585
- Connection(connection_string: str, pool_config: Optional[PoolConfig] = None) -> Connection
586
-
587
- # Usage with async context manager (recommended)
588
- async with Connection(connection_string) as conn:
589
- # Use query() for SELECT statements that return rows
590
- result = await conn.query("SELECT * FROM users")
591
- rows = result.rows()
592
-
593
- # Use execute() for INSERT/UPDATE/DELETE statements that return affected count
594
- affected = await conn.execute("INSERT INTO users (name) VALUES (@P1)", ["John"])
595
- ```
596
-
597
- #### Utility Functions
598
- ```python
599
- version() -> str # Get library version
600
- ```
601
-
602
- ### Connection Pool Architecture
603
-
604
- The library uses the bb8 connection pool for efficient resource management:
605
-
606
- 1. **Pool Initialization**: Creates a pool of reusable connections on first use
607
- 2. **Connection Reuse**: Automatically reuses idle connections for new requests
608
- 3. **Load Balancing**: Distributes connections across concurrent operations
609
- 4. **Automatic Cleanup**: Closes idle connections based on timeout settings
610
- 5. **Thread Safety**: Safe for use across multiple threads and async tasks
611
-
612
- ### Error Handling
613
-
614
- ```python
615
- try:
616
- async with mssql.connect_async(connection_string) as conn:
617
- result = await conn.query("SELECT * FROM invalid_table")
618
- rows = result.rows()
619
- except Exception as e:
620
- print(f"Database error: {e}")
621
- # Connection automatically returned to pool even on error
622
- ```
623
-
624
- ## Migration to Async-Only Architecture
625
-
626
- This library has been upgraded to use async-only operations with the bb8 connection pool for improved performance and reliability.
627
-
628
- **Async-Only API:**
629
- ```python
630
- # Async-only with automatic connection pooling
631
- async with mssql.connect_async(conn_str) as conn:
632
- result = await conn.query("SELECT * FROM table")
633
- rows = result.rows()
634
-
635
- # Pool statistics
636
- stats = conn.pool_stats()
637
- print(f"Pool utilization: {stats['active_connections']}/{stats['connections']}")
638
- ```
639
-
640
- ## Advanced Usage Patterns
641
-
642
- ### Custom Pool Configuration for Different Scenarios
643
-
644
- ```python
645
- from fastmssql import Connection, PoolConfig
646
-
647
- # High-load web application
648
- web_config = PoolConfig(
649
- max_size=50, # Handle many concurrent requests
650
- min_idle=10, # Keep connections ready
651
- max_lifetime_secs=1800, # 30 min connection lifetime
652
- idle_timeout_secs=300, # 5 min idle timeout
653
- connection_timeout_secs=10 # Fast timeout for web responses
654
- )
655
-
656
- # Batch processing application
657
- batch_config = PoolConfig(
658
- max_size=5, # Fewer connections
659
- min_idle=2, # Always keep some ready
660
- max_lifetime_secs=7200, # 2 hour lifetime for long operations
661
- idle_timeout_secs=1800, # 30 min idle timeout
662
- connection_timeout_secs=60 # Longer timeout for batch work
663
- )
664
-
665
- # Microservice with limited resources
666
- micro_config = PoolConfig(
667
- max_size=3, # Minimal connections
668
- min_idle=1, # One always ready
669
- max_lifetime_secs=3600, # 1 hour lifetime
670
- idle_timeout_secs=600, # 10 min idle timeout
671
- connection_timeout_secs=15 # Quick timeout
672
- )
673
- ```
674
-
675
- ### Monitoring Pool Health
676
-
677
- ```python
678
- async def monitor_database_pool():
679
- """Monitor connection pool health and performance"""
680
-
681
- async with mssql.connect_async(connection_string) as conn:
682
- while True:
683
- stats = conn.pool_stats()
684
- utilization = stats['active_connections'] / stats['connections'] * 100
685
-
686
- print(f"Pool Utilization: {utilization:.1f}%")
687
- print(f"Active: {stats['active_connections']}, Idle: {stats['idle_connections']}")
688
-
689
- # Alert if pool utilization is too high
690
- if utilization > 90:
691
- print("WARNING: High pool utilization detected!")
692
-
693
- await asyncio.sleep(30) # Check every 30 seconds
694
- ```
695
-
696
- ### Optimizing for Different Database Workloads
697
-
698
- ```python
699
- # OLTP (Online Transaction Processing) - Many small, fast queries
700
- oltp_config = PoolConfig.high_throughput()
701
- async def oltp_operations():
702
- async with mssql.connect_async(conn_str, oltp_config) as conn:
703
- # Fast, concurrent transactions
704
- tasks = [
705
- conn.query("SELECT * FROM users WHERE id = @P1", [user_id])
706
- for user_id in range(1, 101)
707
- ]
708
- results = await asyncio.gather(*tasks)
709
-
710
- # OLAP (Online Analytical Processing) - Fewer, longer-running queries
711
- olap_config = PoolConfig.low_resource()
712
- async def olap_operations():
713
- async with mssql.connect_async(conn_str, olap_config) as conn:
714
- # Long-running analytical queries
715
- result = await conn.query("""
716
- SELECT
717
- DATE_TRUNC('quarter', order_date) as quarter,
718
- SUM(total_amount) as total_revenue,
719
- COUNT(*) as order_count
720
- FROM orders
721
- WHERE order_date >= '2024-01-01'
722
- GROUP BY DATE_TRUNC('quarter', order_date)
723
- ORDER BY quarter
724
- """)
725
- return result.rows()
726
- ```
727
-
728
- ## API Reference
729
-
730
- ### Common Issues
731
-
732
- 1. **Import Error**: Make sure you've built the extension with `maturin develop`
733
- 2. **Connection Fails**: Check your connection string and SQL Server configuration. Note that Windows authentication is not supported - use SQL Server authentication with username and password.
734
- 3. **Build Errors**: Ensure you have the Rust toolchain installed
735
- 4. **Build Issues**: Make sure you have the Microsoft Visual C++ Build Tools on Windows
736
-
737
-
738
- ## Contributing
739
-
740
- Contributions are welcome! Please open an issue or submit a pull request for any enhancements or bug fixes.
741
-
742
-
743
- ## License
744
-
745
- FastMSSQL is available under your choice of two licenses:
746
-
747
- ### Option 1: GNU General Public License v3.0 (GPL-3.0)
748
-
749
- **Free for open source projects.** If you distribute your application, you must make your entire application open source under GPL-3.0.
750
-
751
- ### Option 2: Commercial License
752
-
753
- **Paid license for proprietary applications.** Allows you to keep your application closed source. Contact riverb514@gmail.com for commercial licensing.
754
-
755
- See the [LICENSE](LICENSE) file for full GPL-3.0 terms and commercial licensing details.
756
-
757
- ### Examples and Benchmarks
758
-
759
- - **Examples Directory**: All files in the `examples/` directory are licensed under the MIT License. See `examples/LICENSE` for full terms.
760
- - **Benchmarks Directory**: All files in the `benchmarks/` directory are licensed under the MIT License. See `licenses/MIT_LICENSE.txt` for full terms.
761
-
762
- ## Third-Party Attributions
763
-
764
- This project includes and depends on third-party libraries licensed under the Apache License 2.0 and MIT License, as well as other open source licenses.
765
-
766
- **Note:** Additional third-party libraries and their license information are listed in `licenses/NOTICE.txt`.
767
-
768
- - [Tiberius](https://github.com/prisma/tiberius) (Apache License 2.0)
769
- - [PyO3](https://github.com/PyO3/pyo3) (Apache License 2.0)
770
- - [pyo3-asyncio](https://github.com/PyO3/pyo3-asyncio) (Apache License 2.0)
771
- - [bb8](https://github.com/djc/bb8) (MIT or Apache License 2.0)
772
- - [bb8-tiberius](https://github.com/prisma/tiberius) (Apache License 2.0)
773
- - [tokio](https://github.com/tokio-rs/tokio) (MIT or Apache License 2.0)
774
- - [tokio-util](https://github.com/tokio-rs/tokio) (MIT or Apache License 2.0)
775
- - [futures](https://github.com/rust-lang/futures-rs) (MIT or Apache License 2.0)
776
- - [serde](https://github.com/serde-rs/serde) (MIT or Apache License 2.0)
777
- - [serde_json](https://github.com/serde-rs/json) (MIT or Apache License 2.0)
778
- - [anyhow](https://github.com/dtolnay/anyhow) (MIT or Apache License 2.0)
779
- - [chrono](https://github.com/chronotope/chrono) (MIT or Apache License 2.0)
780
- - [uuid](https://github.com/uuid-rs/uuid) (MIT or Apache License 2.0)
781
- - [tempfile](https://github.com/Stebalien/tempfile) (MIT or Apache License 2.0)
782
- - [pytest](https://github.com/pytest-dev/pytest) (MIT License)
783
- - [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) (MIT License)
784
- - [black](https://github.com/psf/black) (MIT License)
785
- - [ruff](https://github.com/astral-sh/ruff) (MIT License)
786
- - [maturin](https://github.com/PyO3/maturin) (Apache License 2.0 or MIT License)
787
- - [Python](https://www.python.org/) and [asyncio](https://docs.python.org/3/library/asyncio.html) (Python Software Foundation License)
788
-
789
- See the `licenses/NOTICE.txt` file for full attribution and copyright information.
790
- The full text of the Apache License 2.0 is provided in the `licenses/APACHE_LICENSE_2.0.txt` file.
791
- The full text of the MIT License is provided in the `licenses/MIT_LICENSE.txt` file.
792
-
793
- ## Acknowledgments
794
-
795
- - [Tiberius](https://github.com/prisma/tiberius) - Rust SQL Server driver (Apache License 2.0)
796
- - [PyO3](https://github.com/PyO3/pyo3) - Python bindings for Rust (Apache License 2.0)
797
- - [pyo3-asyncio](https://github.com/PyO3/pyo3-asyncio) - Async bridge for PyO3 (Apache License 2.0)
798
- - [pytest](https://github.com/pytest-dev/pytest) - Python testing framework (MIT License)
799
- - [pytest-asyncio](https://github.com/pytest-dev/pytest-asyncio) - Async test support for pytest (MIT License)
800
- - [black](https://github.com/psf/black) - Python code formatter (MIT License)
801
- - [ruff](https://github.com/astral-sh/ruff) - Python linter (MIT License)
802
- - [Python](https://www.python.org/) and [asyncio](https://docs.python.org/3/library/asyncio.html) - Python standard library (Python Software Foundation License)
803
- - [Maturin](https://github.com/PyO3/maturin) - Build tool for Python extensions in Rust