Skip to main content

A high-performance async Python library for Microsoft SQL Server built on Rust for heavy workloads and low latency.

Project description

FastMSSQL ⚡

FastMSSQL is an async Python library for Microsoft SQL Server (MSSQL), built in Rust. Unlike standard libaries, it uses a native SQL Server client—no ODBC required—simplifying installation on Windows, macOS, and Linux. Great for data ingestion, bulk inserts, and large-scale query workloads.

Python Versions

License

Unit Tests

Latest Release

Platform

Rust Backend

Features

  • High performance: optimized for very high RPS and low overhead
  • Rust core: memory‑safe and reliable, tuned Tokio runtime
  • No ODBC: native SQL Server client, no external drivers needed
  • Connection pooling: bb8‑based, smart defaults (default max_size=10, min_idle=2)
  • Async first: clean async/await API with async with context managers
  • Strong typing: fast conversions for common SQL Server types
  • Thread‑safe: safe to use in concurrent apps
  • Cross‑platform: Windows, macOS, Linux
  • Batch operations: high-performance bulk inserts and batch query execution

Key API methods

Core methods for individual operations:

  • query() — SELECT statements that return rows
  • execute() — INSERT/UPDATE/DELETE/DDL that return affected row count
# Use query() for SELECT statements
result = await conn.query("SELECT * FROM users WHERE age > @P1", [25])
rows = result.rows()

# Use execute() for data modification
affected = await conn.execute("INSERT INTO users (name) VALUES (@P1)", ["John"])

Installation

From PyPI (recommended)

pip install fastmssql

Prerequisites

  • Python 3.10 to 3.14
  • Microsoft SQL Server (any recent version)

Quick start

Basic async usage

import asyncio
from fastmssql import Connection

async def main():
    conn_str = "Server=localhost;Database=master;User Id=myuser;Password=mypass"
    async with Connection(conn_str) as conn:
        # SELECT: use query() -> rows()
        result = await conn.query("SELECT @@VERSION as version")
        for row in result.rows():
            print(row['version'])

        # Pool statistics (tuple: connected, connections, idle, max_size, min_idle)
        connected, connections, idle, max_size, min_idle = await conn.pool_stats()
        print(f"Pool: connected={connected}, size={connections}/{max_size}, idle={idle}, min_idle={min_idle}")

asyncio.run(main())

Explicit Connection Management

When not utilizing Python's context manager (async with), FastMssql uses lazy connection initialization:
if you call query() or execute() on a new Connection, the underlying pool is created if not already present.

For more control, you can explicitly connect and disconnect:

import asyncio
from fastmssql import Connection

async def main():
    conn_str = "Server=localhost;Database=master;User Id=myuser;Password=mypass"
    conn = Connection(conn_str)

    # Explicitly connect
    await conn.connect()
    assert await conn.is_connected()

    # Run queries
    result = await conn.query("SELECT 42 as answer")
    print(result.rows()[0]["answer"])  # -> 42

    # Explicitly disconnect
    await conn.disconnect()
    assert not await conn.is_connected()
    
asyncio.run(main())

Usage

Connection options

You can connect either with a connection string or individual parameters.

  1. Connection string
import asyncio
from fastmssql import Connection

async def main():
    conn_str = "Server=localhost;Database=master;User Id=myuser;Password=mypass"
    async with Connection(connection_string=conn_str) as conn:
        rows = (await conn.query("SELECT DB_NAME() as db")).rows()
        print(rows[0]['db'])

asyncio.run(main())
  1. Individual parameters
import asyncio
from fastmssql import Connection

async def main():
    async with Connection(
        server="localhost",
        database="master",
        username="myuser",
        password="mypassword"
    ) as conn:
        rows = (await conn.query("SELECT SUSER_SID() as sid")).rows()
        print(rows[0]['sid'])

asyncio.run(main())

Note: Windows authentication (Trusted Connection) is currently not supported. Use SQL authentication (username/password).

Working with data

import asyncio
from fastmssql import Connection

async def main():
    async with Connection("Server=.;Database=MyDB;User Id=sa;Password=StrongPwd;") as conn:
        # SELECT (returns rows)
        users = (await conn.query(
            "SELECT id, name, email FROM users WHERE active = 1"
        )).rows()
        for u in users:
            print(f"User {u['id']}: {u['name']} ({u['email']})")

        # INSERT / UPDATE / DELETE (returns affected row count)
        inserted = await conn.execute(
            "INSERT INTO users (name, email) VALUES (@P1, @P2)",
            ["Jane", "jane@example.com"],
        )
        print(f"Inserted {inserted} row(s)")

        updated = await conn.execute(
            "UPDATE users SET last_login = GETDATE() WHERE id = @P1",
            [123],
        )
        print(f"Updated {updated} row(s)")

asyncio.run(main())

Parameters use positional placeholders: @P1, @P2, ... Provide values as a list in the same order.

Batch operations

For high-throughput scenarios, use batch methods to reduce network round-trips:

import asyncio
from fastmssql import Connection

async def main_fetching():
    # Replace with your actual connection string
    async with Connection("Server=.;Database=MyDB;User Id=sa;Password=StrongPwd;") as conn:
        
        # --- 1. Prepare Data for Demonstration ---
        columns = ["name", "email", "age"]
        data_rows = [
            ["Alice Johnson", "alice@example.com", 28],
            ["Bob Smith", "bob@example.com", 32],
            ["Carol Davis", "carol@example.com", 25],
            ["David Lee", "david@example.com", 35],
            ["Eva Green", "eva@example.com", 29]
        ]
        await conn.bulk_insert("users", columns, data_rows)

        # --- 2. Execute Query and Retrieve the Result Object ---
        print("\n--- Result Object Fetching (fetchone, fetchmany, fetchall) ---")
        
        # The Result object is returned after the awaitable query executes.
        result = await conn.query("SELECT name, age FROM users ORDER BY age DESC")
        
        # fetchone(): Retrieves the next single row synchronously.
        oldest_user = result.fetchone() 
        if oldest_user:
            print(f"1. fetchone: Oldest user is {oldest_user['name']} (Age: {oldest_user['age']})")
        
        # fetchmany(2): Retrieves the next set of rows synchronously.
        next_two_users = result.fetchmany(2)
        print(f"2. fetchmany: Retrieved {len(next_two_users)} users: {[r['name'] for r in next_two_users]}.")
        
        # fetchall(): Retrieves all remaining rows synchronously.
        remaining_users = result.fetchall()
        print(f"3. fetchall: Retrieved all {len(remaining_users)} remaining users: {[r['name'] for r in remaining_users]}.")
        
        # Exhaustion Check: Subsequent calls return None/[]
        print(f"4. Exhaustion Check (fetchone): {result.fetchone()}")
        print(f"5. Exhaustion Check (fetchmany): {result.fetchmany(1)}")

        # --- 3. Batch Commands for multiple operations ---
        print("\n--- Batch Commands (execute_batch) ---")
        commands = [
            ("UPDATE users SET last_login = GETDATE() WHERE name = @P1", ["Alice Johnson"]),
            ("INSERT INTO user_logs (action, user_name) VALUES (@P1, @P2)", ["login", "Alice Johnson"])
        ]
        
        affected_counts = await conn.execute_batch(commands)
        print(f"Updated {affected_counts[0]} users, inserted {affected_counts[1]} logs")
        
asyncio.run(main_fetching())

Connection pooling

Tune the pool to fit your workload. Constructor signature:

from fastmssql import PoolConfig

# PoolConfig(max_size=10, min_idle=2, max_lifetime_secs=None, idle_timeout_secs=None, connection_timeout_secs=30)
config = PoolConfig(
    max_size=20,              # max connections in pool
    min_idle=5,               # keep at least this many idle
    max_lifetime_secs=3600,   # recycle connections after 1h
    idle_timeout_secs=600,    # close idle connections after 10m
    connection_timeout_secs=30
)

Presets:

high  = PoolConfig.high_throughput()         # ~ max_size=50,  min_idle=15
low   = PoolConfig.low_resource()            # ~ max_size=3,   min_idle=1
dev   = PoolConfig.development()             # ~ max_size=5,   min_idle=1
maxp  = PoolConfig.maximum_performance()     # ~ max_size=100, min_idle=30
ultra = PoolConfig.ultra_high_concurrency()  # ~ max_size=200, min_idle=50

Apply to a connection:

async with Connection(conn_str, pool_config=high) as conn:
    rows = (await conn.query("SELECT 1 AS ok")).rows()

Default pool (if omitted): max_size=10, min_idle=2.

SSL/TLS

For Required and LoginOnly encryption, you must specify how to validate the server certificate:

Option 1: Trust Server Certificate (development/self-signed certs):

from fastmssql import SslConfig, EncryptionLevel, Connection

ssl = SslConfig(
    encryption_level=EncryptionLevel.Required,
    trust_server_certificate=True
)

async with Connection(conn_str, ssl_config=ssl) as conn:
    ...

Option 2: Custom CA Certificate (production):

from fastmssql import SslConfig, EncryptionLevel, Connection

ssl = SslConfig(
    encryption_level=EncryptionLevel.Required,
    ca_certificate_path="/path/to/ca-cert.pem"
)

async with Connection(conn_str, ssl_config=ssl) as conn:
    ...

Note: trust_server_certificate and ca_certificate_path are mutually exclusive.

Helpers:

  • SslConfig.development() – encrypt, trust all (dev only)
  • SslConfig.with_ca_certificate(path) – use custom CA
  • SslConfig.login_only() / SslConfig.disabled() – legacy modes
  • SslConfig.disabled() – no encryption (not recommended)

Performance tips

For maximum throughput in highly concurrent scenarios, use multiple Connection instances (each with its own pool) and batch your work:

import asyncio
from fastmssql import Connection, PoolConfig

async def worker(conn_str, cfg):
    async with Connection(conn_str, pool_config=cfg) as conn:
        for _ in range(1000):
            _ = (await conn.query("SELECT 1 as v")).rows()

async def main():
    conn_str = "Server=.;Database=master;User Id=sa;Password=StrongPwd;"
    cfg = PoolConfig.high_throughput()
    await asyncio.gather(*[asyncio.create_task(worker(conn_str, cfg)) for _ in range(32)])

asyncio.run(main())

Examples & benchmarks

  • Examples: examples/comprehensive_example.py
  • Benchmarks: benchmarks/

Troubleshooting

  • Import/build: ensure Rust toolchain and maturin are installed if building from source
  • Connection: verify connection string; Windows auth not supported
  • Timeouts: increase pool size or tune connection_timeout_secs
  • Parameters: use @P1, @P2, ... and pass a list of values

Contributing

Contributions are welcome. Please open an issue or PR.

License

FastMSSQL is licensed under MIT:

See the LICENSE file for details.

Third‑party attributions

Built on excellent open source projects: Tiberius, PyO3, pyo3‑asyncio, bb8, tokio, serde, pytest, maturin, and more. See licenses/NOTICE.txt for the full list. The full texts of Apache‑2.0 and MIT are in licenses/.

Acknowledgments

Thanks to the maintainers of Tiberius, PyO3, pyo3‑asyncio, Tokio, pytest, maturin, and the broader open source community.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastmssql-0.4.9.tar.gz (126.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fastmssql-0.4.9-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

fastmssql-0.4.9-cp310-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

fastmssql-0.4.9-cp310-abi3-musllinux_1_1_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.1+ x86-64

fastmssql-0.4.9-cp310-abi3-musllinux_1_1_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.1+ ARM64

fastmssql-0.4.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

fastmssql-0.4.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fastmssql-0.4.9-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (2.3 MB view details)

Uploaded CPython 3.10+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file fastmssql-0.4.9.tar.gz.

File metadata

  • Download URL: fastmssql-0.4.9.tar.gz
  • Upload date:
  • Size: 126.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastmssql-0.4.9.tar.gz
Algorithm Hash digest
SHA256 6c14de9446a65874e91fb67ad65edd5d3256a69ea64c44b214c8535115400eee
MD5 1976b6a3cd2d27650f9157cb0b127dcf
BLAKE2b-256 db0fde865b5d102c1b351b2769ee6d6c04bd4cf0b53a303973b69d7d6df8efdd

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9.tar.gz:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fastmssql-0.4.9-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e237e528bc7fbea68963ad4a56b88bf50ef1e448bc83b283d2ee11dc65f348ed
MD5 7b20e06cdf7b5c88be672fbc3c3a48db
BLAKE2b-256 f50b398d187281726333f7032ec0742e04f003500cf6b81cb7c87a0782bbb76a

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: fastmssql-0.4.9-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastmssql-0.4.9-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f7660ac9188072d0f46026eb86876109cb54331e5600d5985ac7f29f8155266b
MD5 e608cfdc81cf5dd4fdd1bafd00be2465
BLAKE2b-256 b99aefe02cfdd679ebf4b768ce87d6057729cdc2c7a0672cd323a3bffcae0379

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-cp310-abi3-win_amd64.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-cp310-abi3-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for fastmssql-0.4.9-cp310-abi3-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 027ae5af12a9f43ea9f8e57a8042021c26e70512267695387c18e779ae6bda4d
MD5 2e57fce8dca6875387e9d929a31b628e
BLAKE2b-256 1ebd3167f0ac0a8b33f4243fcaf6f1512328f2b2e63669b461d593f86f25f13c

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-cp310-abi3-musllinux_1_1_x86_64.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-cp310-abi3-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for fastmssql-0.4.9-cp310-abi3-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 ba03cf6de55ca0d39eb0a3c916086ba05e86ac3be57ff2fc1a6aa7388c32ea90
MD5 e1a85ce06097481f17e631c484dd8e77
BLAKE2b-256 e61863464f9d4c8e9570d31efe325721207aafbd8c326e743afb0e192a37ade4

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-cp310-abi3-musllinux_1_1_aarch64.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fastmssql-0.4.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a663be848667958c87683f9248bf7b7cc261218b3243cd9814a4e40c13dbe334
MD5 75075ef70a4de5582168f97eec331a55
BLAKE2b-256 75a39bd7eee3470d7f7a4c311afc83cf9d307aa688903d48793ad7ef190b898a

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fastmssql-0.4.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 039e0e946adbd5499092c92a6813804ba8f578298138cedeee85a454f4b588b2
MD5 be543919134cd23ae045e02ab02585c0
BLAKE2b-256 0809c7dd36d260c040d4ad1bbb51392dcd4ebcae71176995f08fe00f0a0412cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastmssql-0.4.9-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for fastmssql-0.4.9-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 bb1f812f9a270d8e0e7e3993f9a7379749ec1080c7444c3b206f4ca035d0c12c
MD5 5f674064b6c3933bda8845c585d4e437
BLAKE2b-256 ff5fe87b9e45ae83dbc67c83e77415d3a6249a46329c5de9b96c2ed28721a9ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastmssql-0.4.9-cp310-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: build-wheels.yml on Rivendael/FastMssql

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page