SQLAlchemy dialect for Excel files — use Excel as a database
Project description
sqlalchemy-excel
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
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
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 sqlalchemy_excel-0.4.0.tar.gz.
File metadata
- Download URL: sqlalchemy_excel-0.4.0.tar.gz
- Upload date:
- Size: 33.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6987152d14a38dd92091f9909a58a772b503bbbebeb359b0fbb08376745be290
|
|
| MD5 |
48e90d14d6fd9ec1d4d15c8b60394eb7
|
|
| BLAKE2b-256 |
b66f6268294bb0694612028d21552ccca5333e8f93d1b800d544cc9ed79951c1
|
Provenance
The following attestation bundles were made for sqlalchemy_excel-0.4.0.tar.gz:
Publisher:
publish-pypi.yml on yeongseon/sqlalchemy-excel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sqlalchemy_excel-0.4.0.tar.gz -
Subject digest:
6987152d14a38dd92091f9909a58a772b503bbbebeb359b0fbb08376745be290 - Sigstore transparency entry: 1280748141
- Sigstore integration time:
-
Permalink:
yeongseon/sqlalchemy-excel@9d16abbdddf48e7d3fe6ba2d936315b28516371e -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/yeongseon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@9d16abbdddf48e7d3fe6ba2d936315b28516371e -
Trigger Event:
release
-
Statement type:
File details
Details for the file sqlalchemy_excel-0.4.0-py3-none-any.whl.
File metadata
- Download URL: sqlalchemy_excel-0.4.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dcf1fd253348ae3ff59f637778b8b27306cec183ab82e192b27fe7cdab5544b0
|
|
| MD5 |
7955a2226f8212b7ffb41eeac11d76f3
|
|
| BLAKE2b-256 |
bb7bb5b091cb718b5dc1fc4ed7bab8172da7085d612910694379464c013880ca
|
Provenance
The following attestation bundles were made for sqlalchemy_excel-0.4.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on yeongseon/sqlalchemy-excel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sqlalchemy_excel-0.4.0-py3-none-any.whl -
Subject digest:
dcf1fd253348ae3ff59f637778b8b27306cec183ab82e192b27fe7cdab5544b0 - Sigstore transparency entry: 1280748144
- Sigstore integration time:
-
Permalink:
yeongseon/sqlalchemy-excel@9d16abbdddf48e7d3fe6ba2d936315b28516371e -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/yeongseon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@9d16abbdddf48e7d3fe6ba2d936315b28516371e -
Trigger Event:
release
-
Statement type: