Skip to main content

Moltres

CI Python 3.10+ License: MIT Documentation Status

The Missing DataFrame Layer for SQL in Python

MOLTRES: Modern Operations Layer for Transformations, Relational Execution, and SQL


Moltres combines a DataFrame API (like Pandas/Polars), SQL pushdown execution (no data loading into memory), and real SQL CRUD operations (INSERT, UPDATE, DELETE) in one unified interface. See why Moltres and the comparison guides for how it differs from Pandas, Ibis, and PySpark.

Transform millions of rows using familiar DataFrame operations—all executed directly in SQL without materializing data.

✨ Key Features

  • 🚀 PySpark-Style DataFrame API - High compatibility for core operations; see migration footguns
  • 🗄️ SQL Pushdown Execution - All operations compile to SQL and run on your database
  • ✏️ Real SQL CRUD - INSERT, UPDATE, DELETE with DataFrame-style syntax
  • 🐼 Pandas & Polars Interfaces - Optional pandas/polars-style APIs
  • Async Support - Full async/await support for all operations
  • 🔒 Security First - Built-in SQL injection prevention
  • 🎯 Framework Integrations - FastAPI, Django, Streamlit, SQLModel, Pydantic

📦 Installation

pip install moltres

# Common optional extras
pip install moltres[pandas,polars]     # Pandas/Polars result formats
pip install moltres[async-postgresql]  # Async PostgreSQL
pip install moltres[parquet,duckdb,fastapi]  # File I/O, DuckDB, FastAPI helpers

# Full extras table: docs/PUBLIC_API.md#optional-extras

moltres-core and pydantable

SQL execution lives in the companion moltres-core package. You can use MoltresPydantableEngine with pydantable for a typed, plan-driven API backed by SQL for supported operations. See docs/PYDANTABLE_ENGINE.md. From source, install moltres-core before moltres:

pip install -e ./moltres-core
pip install -e .

1.1.1 ships this split on PyPI: pip install moltres pulls in moltres-core automatically. For breaking changes and upgrade notes, see CHANGELOG.md.

Prerequisites

  • Python 3.10+ (see Runtime support)
  • SQLAlchemy 2.0+ (installed automatically with moltres)
  • Database driver for your backend (e.g. psycopg2-binary for PostgreSQL, pymysql for MySQL; SQLite needs no extra driver)
  • Optional extras: full list in Public API — Optional extras

🚀 Quick Start

New here? Start with the 5-minute quick start, then the complete tutorial when you want more depth.

from moltres import col, connect
from moltres.expressions import functions as F
from moltres.io.records import Records
from moltres.table.schema import column

with connect("sqlite:///:memory:") as db:
    db.create_table("orders", [
        column("id", "INTEGER"),
        column("country", "TEXT"),
        column("amount", "REAL"),
    ]).collect()
    Records.from_list([
        {"id": 1, "country": "US", "amount": 100.0},
        {"id": 2, "country": "UK", "amount": 200.0},
    ], database=db).insert_into("orders")

    df = (
        db.table("orders").select()
        .where(col("country") == "US")
        .group_by("country")
        .agg(F.sum(col("amount")).alias("total_amount"))
    )
    print(df.collect())  # [{'country': 'US', 'total_amount': 100.0}]

    # CRUD: update and delete rows
    db.update("orders", where=col("country") == "US", set={"amount": 150.0})
    db.delete("orders", where=col("amount") < 50)

For a fuller CRUD walkthrough (separate tables, Records, merge), see the complete tutorial.

Reading Data: Tables vs Files

Goal API Returns
Query a SQL table lazily db.table("orders").select() DataFrame (SQL pushdown)
Load a file as a lazy DataFrame db.load.csv("data.csv") DataFrame (materialized via temp table)
Load a file as in-memory rows db.read.records.csv("data.csv") Records (eager, for inserts)

See Public API guide for stable import paths.

📖 Documentation

Framework Integrations

🛠️ Supported Operations

DataFrame Operations: select(), where(), join(), group_by(), agg(), order_by(), limit(), distinct(), pivot(), and more

130+ Functions: Mathematical, string, date/time, aggregate, window, array, JSON, and utility functions

SQL Dialects: SQLite, PostgreSQL, MySQL, and DuckDB are CI-tested; other SQLAlchemy-supported databases are best-effort (see Runtime support)

UX Features: Enhanced SQL display (show_sql(), sql property), query plan visualization (plan_summary(), visualize_plan()), schema discovery (db.schema(), db.tables()), query validation (validate()), performance hints (performance_hints()), and interactive help (help(), suggest_next())

🧪 Development

From a git checkout, install moltres-core before moltres (the monorepo ships two packages):

pip install -e ./moltres-core
pip install -e ".[dev]"

# Run lint/type/doc-example checks (does NOT run the test suite)
make ci-check

# Run tests (matches CI main matrix)
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 pytest -p pytest_asyncio.plugin -p xdist.plugin \
  -m "not postgres and not mysql and not multidb and not tier2_integration and not tier3_integration" \
  -n auto --dist loadgroup

🤝 Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

📄 License

MIT License - see LICENSE file for details.


Made with ❤️ for the Python data community

⬆ Back to Top

Download files

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

Source Distribution

moltres-1.1.1.tar.gz (371.2 kB view details)

Uploaded Source

Built Distribution

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

moltres-1.1.1-py3-none-any.whl (454.7 kB view details)

Uploaded Python 3

File details

Details for the file moltres-1.1.1.tar.gz.

File metadata

  • Download URL: moltres-1.1.1.tar.gz
  • Upload date:
  • Size: 371.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for moltres-1.1.1.tar.gz
Algorithm Hash digest
SHA256 1fc0f7d3aa0e04a2ddb7c6de355fb13f9181f3908298cddeeb42146344fb976b
MD5 ad169a6c5a87dd224a26d9339efe64d5
BLAKE2b-256 ed2aa225aed2c9aa897bc0213b1a63ddcbd0c0fb4501a105bbaa09a82d507b2a

See more details on using hashes here.

File details

Details for the file moltres-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: moltres-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 454.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for moltres-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c1d5837a15a5db1813c583c941bf530a6b49ac25eb9c9c6faca30bf2481cc38a
MD5 72040cadb9ed7358f7f5db52d76ed3a4
BLAKE2b-256 2be61a038f77b9327b350c53110b07f293c6ea691db3a83f42e63813b1b737c4

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

0.23.2

2 files

0.23.1

2 files

0.23.0

2 files

0.22.0

2 files

0.21.0

2 files

0.20.0

2 files

0.19.6

2 files

0.19.4

2 files

0.19.3

2 files

0.19.2

2 files

0.19.1

2 files

0.19.0

2 files

0.18.0

2 files

0.17.0

2 files

0.16.0

2 files

0.15.0

2 files

0.14.0

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.0

2 files

0.7.0

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

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