Skip to main content

Bulk copy for SQLAlchemy + mssql-python — 10-50x faster writes via SQL Server's native TDS protocol

Project description

sqlalchemy-mssql-bulkcopy

CI PyPI License: MIT

Bulk copy for SQLAlchemy + mssql-python — 10–50× faster writes via SQL Server's native TDS bulk load protocol.

All cursor.bulkcopy() kwargs pass through to the driver. When mssql-python adds new options, this package supports them automatically.

Based on the event hook approach recommended by SQLAlchemy's maintainer.

Install

The mssql+mssqlpython dialect requires SQLAlchemy ≥ 2.1.0b2, which is not yet on PyPI. Install SA from git until then:

pip install "sqlalchemy @ git+https://github.com/sqlalchemy/sqlalchemy.git@main"
pip install sqlalchemy-mssql-bulkcopy

Once SA 2.1 is stable:

pip install sqlalchemy-mssql-bulkcopy

Requires Python ≥ 3.10, SQLAlchemy ≥ 2.1, mssql-python ≥ 1.4.

Usage

Direct (recommended)

No engine configuration needed. Returns the driver result dict.

from sqlalchemy import create_engine
from sqlalchemy_mssql_bulkcopy import bulkcopy

engine = create_engine("mssql+mssqlpython://user:pass@host/db")

with engine.begin() as conn:
    result = bulkcopy(conn, df, "dbo.users", batch_size=50_000)
    print(f"{result['rows_copied']} rows in {result['elapsed_time']:.2f}s")

Accepts DataFrames (columns auto-detected), lists of tuples, generators, or any iterable:

# All driver options pass through as kwargs
result = bulkcopy(
    conn, df, "staging.events",
    batch_size=100_000,
    table_lock=True,
    keep_identity=True,
    check_constraints=True,
    fire_triggers=True,
    keep_nulls=True,
    timeout=300,
    use_internal_transaction=True,
)

Event hook (SA Core / ORM)

Hooks into SQLAlchemy's INSERT workflow. Per-statement opt-in via execution options:

from sqlalchemy_mssql_bulkcopy import register_bulkcopy

engine = create_engine(
    "mssql+mssqlpython://user:pass@host/db",
    use_insertmanyvalues=False,  # required — see note below
)
register_bulkcopy(engine, batch_size=10_000, table_lock=True)

with engine.begin() as conn:
    conn.execute(
        users.insert().execution_options(use_bulkcopy=True),
        rows,
    )

Per-statement overrides use the bulkcopy_ prefix:

stmt = users.insert().execution_options(
    use_bulkcopy=True,
    bulkcopy_batch_size=100_000,
    bulkcopy_fire_triggers=True,
)

Note: register_bulkcopy() raises ValueError if use_insertmanyvalues is not disabled. SA 2.x defaults to multi-row INSERT … VALUES batching which bypasses executemany() entirely — the event hook never fires without this flag. This is a global engine setting: non-bulkcopy inserts will use executemany() instead, which is slightly slower for medium-sized batches. If that matters, use bulkcopy() directly instead.

Pandas

from sqlalchemy_mssql_bulkcopy import bulkcopy_insert_method

df.to_sql("users", engine, method=bulkcopy_insert_method,
          if_exists="append", index=False)

Confirming bulkcopy was used

# Direct — return value
result = bulkcopy(conn, df, "dbo.users")
assert result["rows_copied"] == len(df)

# Event hook — on_complete callback
results = []
register_bulkcopy(engine, on_complete=lambda t, r: results.append(r))

Both approaches log at INFO level: bulkcopy: 1000 rows -> dbo.users (0.050s)

License

MIT

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

sqlalchemy_mssql_bulkcopy-0.1.0.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

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

sqlalchemy_mssql_bulkcopy-0.1.0-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file sqlalchemy_mssql_bulkcopy-0.1.0.tar.gz.

File metadata

File hashes

Hashes for sqlalchemy_mssql_bulkcopy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d2e8bc630343a2e70135b6f2b5590da37140cd38d0491721b9479eada766fa4a
MD5 c487847f202c81804ef0f7a7ecdd262e
BLAKE2b-256 dd4f91d7d465b2f001ffea231bf476dd1892d54870f2284db99822d040edebfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlalchemy_mssql_bulkcopy-0.1.0.tar.gz:

Publisher: publish.yml on dxdc/sqlalchemy-mssql-bulkcopy

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

File details

Details for the file sqlalchemy_mssql_bulkcopy-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sqlalchemy_mssql_bulkcopy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0955fc4e5f83a71548d6cbd3a82c90b99a23a68b9dc765945c80a84f77e0803d
MD5 68167ac19c81e4148036c83a0605df7d
BLAKE2b-256 96ac937008628ffb45c09509b932be3a57057b0c8653b624da8f974126defb73

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlalchemy_mssql_bulkcopy-0.1.0-py3-none-any.whl:

Publisher: publish.yml on dxdc/sqlalchemy-mssql-bulkcopy

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