DuckDB SQLAlchemy dialect for DuckDB and MotherDuck
Project description
duckdb-sqlalchemy
duckdb-sqlalchemy is a DuckDB SQLAlchemy dialect for DuckDB and MotherDuck. It supports SQLAlchemy Core and ORM APIs for local DuckDB and MotherDuck connections.
For new projects, this repository is the recommended dialect when you want production-oriented defaults, explicit MotherDuck guidance, and a clear migration path from older package names.
The dialect handles pooling defaults, bulk inserts, type mappings, and cloud-specific configuration.
Why choose duckdb-sqlalchemy today
- SQLAlchemy compatibility: Core, ORM, Alembic, and reflection.
- MotherDuck support: Token handling, attach modes, session hints, and read scaling helpers.
- Operational defaults: Pooling defaults, transient retry for reads, and bulk insert optimization via Arrow/DataFrame registration.
- Active release cadence: Tracks current DuckDB releases with a long-term support posture.
| Area | duckdb-sqlalchemy (this repo) |
duckdb_engine |
|---|---|---|
| Package/module name | duckdb-sqlalchemy / duckdb_sqlalchemy |
duckdb-engine / duckdb_engine |
| SQLAlchemy driver URL | duckdb:// |
duckdb:// |
| MotherDuck workflow coverage | Dedicated URL helper (MotherDuckURL), connection guidance, and examples |
No dedicated MotherDuck usage section in the upstream README |
| Operational guidance | Documented pooling defaults, read-scaling helpers, and bulk insert patterns | Basic configuration guidance in upstream README |
| Migration path | Explicit migration guide from older package names | Migration to this package is documented in this repo |
| Project direction | Release policy, changelog, roadmap, and docs site are maintained here | Upstream README focuses on the core driver usage |
Coming from duckdb_engine?
If you already use duckdb-engine, migration is straightforward:
- keep the SQLAlchemy URL scheme (
duckdb://) - install
duckdb-sqlalchemy - switch imports to
duckdb_sqlalchemy
See the full guide: docs/migration-from-duckdb-engine.md.
Project lineage
This project is a heavily modified fork of Mause/duckdb_engine and continues to preserve upstream history in CHANGELOG.md.
Current direction in this repository:
- package and module rename to
duckdb-sqlalchemy/duckdb_sqlalchemy - production-oriented defaults for local DuckDB and MotherDuck deployments
- docs-first maintenance with versioned release notes and a published docs site
Compatibility
| Component | Supported versions |
|---|---|
| Python | 3.9+ |
| SQLAlchemy | 1.3.22+ (CI-tested: 1.3, 1.4, 2.0.48) |
| DuckDB | 0.5.0+ (CI-tested currently: 1.1.3 to 1.5.1) |
Install
pip install duckdb-sqlalchemy
Quick start (DuckDB)
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import declarative_base, Session
Base = declarative_base()
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
name = Column(String)
engine = create_engine("duckdb:///:memory:")
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(User(name="Ada"))
session.commit()
assert session.query(User).one().name == "Ada"
Quick start (MotherDuck)
export MOTHERDUCK_TOKEN="..."
from sqlalchemy import create_engine
engine = create_engine("duckdb:///md:my_db")
MotherDuck uses the md: database prefix. Tokens are picked up from MOTHERDUCK_TOKEN (or motherduck_token) automatically. If your token has special characters, URL-escape it or pass it via connect_args.
Connection URLs
DuckDB URLs follow the standard SQLAlchemy shape:
duckdb:///<database>?<config>
Examples:
duckdb:///:memory:
duckdb:///analytics.db
duckdb:////absolute/path/to/analytics.db
duckdb:///md:my_db?attach_mode=single&access_mode=read_only&session_hint=team-a
Use the URL helpers to build connection strings safely:
from duckdb_sqlalchemy import URL, MotherDuckURL
local_url = URL(database=":memory:", memory_limit="1GB")
md_url = MotherDuckURL(database="md:my_db", attach_mode="single")
Configuration and pooling
This dialect defaults to SingletonThreadPool for exact :memory:, QueuePool for named in-memory and empty database URLs, and NullPool for file/MotherDuck connections. You can override pooling explicitly. For long-lived MotherDuck pools, use the performance helper or configure QueuePool, pool_pre_ping, and pool_recycle.
See docs/configuration.md and docs/motherduck.md for detailed guidance.
For manual WAL syncs after SQLAlchemy writes, prefer the explicit
duckdb_sqlalchemy.checkpoint(conn) helper over issuing raw CHECKPOINT
through a transactional SQLAlchemy connection.
Documentation
- docs/index.md - GitHub Pages entrypoint
- docs/README.md - Docs index
- docs/overview.md - Overview and quick start
- docs/getting-started.md - Minimal install + setup walkthrough
- docs/migration-from-duckdb-engine.md - Migration guide from older dialects
- docs/connection-urls.md - URL formats and helpers
- docs/motherduck.md - MotherDuck setup and options
- docs/configuration.md - Connection configuration, extensions, filesystems
- docs/olap.md - Parquet/CSV scans and ATTACH workflows
- docs/pandas-jupyter.md - DataFrame registration and notebook usage
- docs/types-and-caveats.md - Type support and known caveats
- docs/alembic.md - Alembic integration
Docs site (GitHub Pages):
https://leonardovida.github.io/duckdb-sqlalchemy/
Examples
- examples/sqlalchemy_example.py - end-to-end example
- examples/motherduck_read_scaling_per_user.py - per-user read scaling pattern
- examples/motherduck_queuepool_high_concurrency.py - QueuePool tuning
- examples/motherduck_multi_instance_pool.py - multi-instance pool rotation
- examples/motherduck_arrow_reads.py - Arrow results + streaming
- examples/motherduck_attach_modes.py - workspace vs single attach mode
Development workflow
Install development dependencies:
pip install -e ".[dev,devtools]"
Run quick checks in your current environment:
pytest
nox -s ty
pre-commit run --all-files
Run the full compatibility matrix (slow):
nox -s tests
Release and support policy
- Long-term maintenance: intended to remain supported.
- Compatibility: track current DuckDB and SQLAlchemy releases while preserving SQLAlchemy semantics.
- Breaking changes: only in major/minor releases with explicit notes in
CHANGELOG.md. - Security: open an issue with details; fixes are prioritized.
Changelog and roadmap
- CHANGELOG.md - release notes
- ROADMAP.md - upcoming work and priorities
Contributing
See AGENTS.md for repo-specific workflow, tooling, and PR expectations. We welcome issues, bug reports, and high-quality pull requests.
License
MIT. See LICENSE.txt.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file duckdb_sqlalchemy-1.5.1.tar.gz.
File metadata
- Download URL: duckdb_sqlalchemy-1.5.1.tar.gz
- Upload date:
- Size: 191.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17a67c128d70ab8fa35ebace64bb7ec8743ade70a4c524ee9b5d7144e0f7c19b
|
|
| MD5 |
b713e05ec00f31922a5ed8f5ad6b70ef
|
|
| BLAKE2b-256 |
5796eab5a23b13974002cf24d86724fc75cf188b0ad3952aff224d7ad2079193
|
Provenance
The following attestation bundles were made for duckdb_sqlalchemy-1.5.1.tar.gz:
Publisher:
publish.yaml on leonardovida/duckdb-sqlalchemy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duckdb_sqlalchemy-1.5.1.tar.gz -
Subject digest:
17a67c128d70ab8fa35ebace64bb7ec8743ade70a4c524ee9b5d7144e0f7c19b - Sigstore transparency entry: 1185326752
- Sigstore integration time:
-
Permalink:
leonardovida/duckdb-sqlalchemy@b61146d35b1263adc25de15cca2a7a8e049d1f56 -
Branch / Tag:
refs/tags/v1.5.1 - Owner: https://github.com/leonardovida
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@b61146d35b1263adc25de15cca2a7a8e049d1f56 -
Trigger Event:
release
-
Statement type:
File details
Details for the file duckdb_sqlalchemy-1.5.1-py3-none-any.whl.
File metadata
- Download URL: duckdb_sqlalchemy-1.5.1-py3-none-any.whl
- Upload date:
- Size: 54.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6beaec468e172c7397f1cfc9193f2e9b168a4ef8f5def2e415301e600cb7ffbc
|
|
| MD5 |
176c244a9331be0414e5c0c7c75e4081
|
|
| BLAKE2b-256 |
bb288f34f4df8b347101f05d76dbafe14ebb870e3bc9541ecd32dc26383c836d
|
Provenance
The following attestation bundles were made for duckdb_sqlalchemy-1.5.1-py3-none-any.whl:
Publisher:
publish.yaml on leonardovida/duckdb-sqlalchemy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duckdb_sqlalchemy-1.5.1-py3-none-any.whl -
Subject digest:
6beaec468e172c7397f1cfc9193f2e9b168a4ef8f5def2e415301e600cb7ffbc - Sigstore transparency entry: 1185326779
- Sigstore integration time:
-
Permalink:
leonardovida/duckdb-sqlalchemy@b61146d35b1263adc25de15cca2a7a8e049d1f56 -
Branch / Tag:
refs/tags/v1.5.1 - Owner: https://github.com/leonardovida
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@b61146d35b1263adc25de15cca2a7a8e049d1f56 -
Trigger Event:
release
-
Statement type: