Skip to main content

sqlalchemy-excel sqlalchemy-excel

CI codecov PyPI Python 3.10+ License: MIT Docs

SQLAlchemy dialect for Excel files — use Excel worksheets as database tables. This is a narrow-scope dialect: it supports basic CRUD and ORM mapping, but not relational features like JOINs or aggregations.

Limitations (Read First)

Before writing any code, understand what this dialect cannot do:

Feature Supported?
SELECT with WHERE, ORDER BY, LIMIT ✅
INSERT, UPDATE, DELETE ✅
CREATE TABLE / DROP TABLE ✅
ORM with DeclarativeBase ✅
Schema inspection (tables, columns) ✅
IN, BETWEEN, LIKE operators ✅
JOIN (any variant) ❌
GROUP BY / HAVING ❌
DISTINCT ❌
OFFSET ❌
Subqueries / CTEs ❌
Aggregate functions (COUNT, SUM, ...) ❌
ALTER TABLE ❌
Foreign keys / indexes ❌
Concurrent writes ❌
Session.rollback() No-op (data persists)

If you need any of the ❌ features, use SQLite, PostgreSQL, or another full-featured database.


Installation

pip install sqlalchemy-excel

excel-dbapi is automatically installed as a dependency.

Quick Start

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import DeclarativeBase, Session, Mapped, mapped_column

engine = create_engine("excel:///data.xlsx")

class Base(DeclarativeBase):
    pass

class User(Base):
    __tablename__ = "Sheet1"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column()

Base.metadata.create_all(engine)

with Session(engine) as session:
    session.add(User(id=1, name="Alice"))
    session.commit()

with Session(engine) as session:
    users = session.query(User).all()

URL Format

# Relative path
engine = create_engine("excel:///data.xlsx")

# Absolute path (note four slashes)
engine = create_engine("excel:////home/user/data.xlsx")

# With engine options
engine = create_engine("excel:///data.xlsx", connect_args={"engine": "openpyxl"})

Type Mapping

SQLAlchemy Type Excel Storage Notes
String, Text, VARCHAR, CHAR TEXT All string types map to TEXT
Integer, SmallInteger, BigInteger INTEGER All integer types map to INTEGER
Float, Numeric, Decimal FLOAT All numeric types map to FLOAT
Boolean BOOLEAN
Date DATE
DateTime, TIMESTAMP DATETIME
Time TEXT Stored as text
Uuid TEXT Stored as text

BLOB, BINARY, JSON, and ARRAY types are not supported and will raise CompileError.

ORM Examples

Define a Model

from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase, Session, Mapped, mapped_column

engine = create_engine("excel:///data.xlsx")

class Base(DeclarativeBase):
    pass

class User(Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column()
    age: Mapped[int] = mapped_column()

Base.metadata.create_all(engine)

Insert

with Session(engine) as session:
    session.add(User(id=1, name="Alice", age=30))
    session.add(User(id=2, name="Bob", age=25))
    session.commit()

Query with Filters

from sqlalchemy import select

with Session(engine) as session:
    # Basic query
    users = session.query(User).all()

    # WHERE clause
    user = session.query(User).filter(User.name == "Alice").first()

    # IN operator
    stmt = select(User).where(User.name.in_(["Alice", "Bob"]))
    users = session.scalars(stmt).all()

    # BETWEEN operator
    stmt = select(User).where(User.age.between(25, 35))
    users = session.scalars(stmt).all()

    # LIKE operator
    stmt = select(User).where(User.name.like("A%"))
    users = session.scalars(stmt).all()

    # ORDER BY + LIMIT
    stmt = select(User).order_by(User.age.desc()).limit(5)
    users = session.scalars(stmt).all()

Update and Delete

with Session(engine) as session:
    user = session.query(User).filter(User.id == 1).first()
    if user:
        user.name = "Ann"
        session.commit()

with Session(engine) as session:
    user = session.query(User).filter(User.id == 2).first()
    if user:
        session.delete(user)
        session.commit()

Core Usage

from sqlalchemy import create_engine, text

engine = create_engine("excel:///data.xlsx")

with engine.connect() as conn:
    result = conn.execute(text("SELECT * FROM Sheet1"))
    for row in result:
        print(row)

Schema Inspection

from sqlalchemy import create_engine, inspect

engine = create_engine("excel:///data.xlsx")
inspector = inspect(engine)

# List all sheets (tables)
print(inspector.get_table_names())

# Get column info
print(inspector.get_columns("Sheet1"))

# Check if a sheet exists
print(inspector.has_table("Sheet1"))

Experimental: Remote Excel via Microsoft Graph API

Status: Experimental — API may change in future releases.

Access Excel files on OneDrive/SharePoint directly:

pip install sqlalchemy-excel[graph]
from sqlalchemy import create_engine
from azure.identity import DefaultAzureCredential

engine = create_engine(
    "excel+graph:///drive_id/item_id",
    connect_args={"credential": DefaultAzureCredential()},
)

with engine.connect() as conn:
    result = conn.execute(text("SELECT * FROM Sheet1"))
    for row in result:
        print(row)

URL format: excel+graph:///drive_id/item_id where drive_id and item_id are Microsoft Graph resource identifiers. Query parameters: ?readonly=false to enable write operations.


Related Projects

  • excel-dbapi — The underlying PEP 249 DB-API 2.0 driver for Excel files.

License

MIT

Metadata

Release files for sqlalchemy-excel 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sqlalchemy-excel 0.4.0
File Size Uploaded
sqlalchemy_excel-0.4.0.tar.gz 33.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sqlalchemy-excel 0.4.0
File Interpreter ABI Platform
sqlalchemy_excel-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 47.2 kB

Release files / sqlalchemy_excel-0.4.0.tar.gz

Download URL sqlalchemy_excel-0.4.0.tar.gz
Size 33.8 kB
Tags Source
SHA-256 checksum
How to use checksums
6987152d14a38dd92091f9909a58a772b503bbbebeb359b0fbb08376745be290
BLAKE2b-256 checksum
How to use checksums
b66f6268294bb0694612028d21552ccca5333e8f93d1b800d544cc9ed79951c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 12, 2026.

Transparency log

Release files / sqlalchemy_excel-0.4.0-py3-none-any.whl

Download URL sqlalchemy_excel-0.4.0-py3-none-any.whl
Size 13.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dcf1fd253348ae3ff59f637778b8b27306cec183ab82e192b27fe7cdab5544b0
BLAKE2b-256 checksum
How to use checksums
bb7bb5b091cb718b5dc1fc4ed7bab8172da7085d612910694379464c013880ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page