Portable SQLAlchemy repository kit: sync and async CRUD, statement builders, sort/pagination, and SQL helpers.
Project description
sqlphilosophy
Portable SQLAlchemy repository kit: sync and async CRUD, fluent statement builders, sort/pagination, Core SQL helpers, and optional audit listeners.
| PyPI | sqlphilosophy |
| GitHub | SignalSafeSoftware/sqlphilosophy |
| Import | sqlphilosophy (__version__ only) — use explicit submodules for APIs |
| Python | 3.12+ |
| License | MIT — see LICENSE |
Documentation
| Resource | Description |
|---|---|
| Repository guide | Entry point: overview, transaction model, links to usage pages |
| Usage examples | Focused sync/async code examples by feature area |
| Strongly typed repositories | Typed subclasses, factories, protocols, and service patterns |
| Service factory composition | Compose sqlPhilosophy SQL repos with servicePhilosophy business services |
| Before/after SQLAlchemy | Migration examples: direct SQLAlchemy vs repository-centered code |
| Feature matrix | Full sync/async capability map |
| Typed repository (sync) | Runnable factory + domain repo example |
| Typed repository (async) | Async counterpart |
What this package does
- Repository pattern for a single mapped model (
BaseRepository,AsyncBaseRepository). - Fluent query builders with pagination/sort (
StatementQueryBuilder,ListQuery,SortConfig). - SQL helpers for row mapping, partial updates, and developer-defined fragments via
sqlphilosophy.trusted_sql. - Optional audit listeners and timestamp mixins.
What this package does not do
- Migrations, schema design, or connection pooling configuration.
- Authorization, multi-tenant isolation, or query sandboxing.
- Automatic commits for normal CRUD — see Transaction ownership.
Install
pip install sqlphilosophy
Async ORM (AsyncSession) also needs greenlet:
pip install sqlphilosophy[async]
Requires Python 3.12+ and SQLAlchemy 2.x.
Quick start (sync)
from sqlalchemy import String, create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, Session, mapped_column, sessionmaker
from sqlphilosophy.sorting import ListQuery
from sqlphilosophy.sync.repository import BaseRepository
class Base(DeclarativeBase):
pass
class Widget(Base):
__tablename__ = "widget"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(64))
engine = create_engine("sqlite:///:memory:", future=True)
Base.metadata.create_all(engine)
SessionLocal = sessionmaker(bind=engine, expire_on_commit=False)
with SessionLocal() as session:
repo = BaseRepository(Widget, session)
repo.create(name="alpha") # stages + flush; does not commit
session.commit()
rows, total = repo.statement().fetch_page(ListQuery.from_page(page=1, size=20))
assert total >= 1
Async: use AsyncSession, AsyncBaseRepository from sqlphilosophy.aio.repository, and await on repository/builder terminals. See the repository guide.
Package layout
| Module | Contents |
|---|---|
sqlphilosophy |
__version__ only |
sqlphilosophy.types |
Portable typing aliases |
sqlphilosophy.sql |
Row mapping, partial updates, Core helpers (re-exports trusted_sql) |
sqlphilosophy.trusted_sql |
Developer-trusted SQL fragments — see SECURITY.md |
sqlphilosophy.sorting |
ListQuery, SortConfig, SortSpec |
sqlphilosophy.sync / sqlphilosophy.aio |
Repositories, query builders, factory protocols |
sqlphilosophy.audit |
Optional listeners and timestamp mixins |
Transaction ownership
create/add/update_partial/remove/delete_*/update_where— flush or execute DML; caller commits.delete_all()— bulk delete; does not commit.batched_purge_ids(..., batch_size=...)— deletes in batches and commits after each batch; requiresbatch_size >= 1. Authorize in application code first.
Raw SQL trust boundaries
Identifiers and SQL fragments (table/column names, ORDER BY text, sort allowlists) must be developer-defined, never built from end-user input. User values use bind parameters.
Import trusted helpers from sqlphilosophy.trusted_sql (sql_table, col_eq, col_icontains, col_range, literal_order_expr, …). The same names are re-exported from sqlphilosophy.sql. Details: SECURITY.md and the repository guide.
Development
uv sync --extra dev
uv run pytest
uv run ruff check src tests docs/examples
uv run ruff format src tests docs/examples
# Optional: validate runnable docs examples (SQLite in-memory; CI runs these in smoke-package)
uv run --extra dev python docs/examples/typed_repository_sync.py
uv run --extra dev python docs/examples/typed_repository_async.py
uv run python -m build
Security
See SECURITY.md for vulnerability reporting and SQL trust boundaries.
Releasing
See RELEASING.md for GitHub + PyPI trusted publishing. See CHANGELOG.md.
License
MIT — see LICENSE.
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 sqlphilosophy-0.2.0.tar.gz.
File metadata
- Download URL: sqlphilosophy-0.2.0.tar.gz
- Upload date:
- Size: 28.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f383c27b52d51530cec68742cac6958f7809a47133808b5c76a185e7da3399f6
|
|
| MD5 |
43a3357330667bf9b96d71be140273d0
|
|
| BLAKE2b-256 |
91420b784623adc34ac3b115e6590e22af9ccfe0b702a2551097ffdb787cac77
|
Provenance
The following attestation bundles were made for sqlphilosophy-0.2.0.tar.gz:
Publisher:
ci.yml on SignalSafeSoftware/sqlphilosophy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sqlphilosophy-0.2.0.tar.gz -
Subject digest:
f383c27b52d51530cec68742cac6958f7809a47133808b5c76a185e7da3399f6 - Sigstore transparency entry: 2135052670
- Sigstore integration time:
-
Permalink:
SignalSafeSoftware/sqlphilosophy@7cce2c2f5ec7e57517a0b806145f3c5c297dbc81 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/SignalSafeSoftware
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@7cce2c2f5ec7e57517a0b806145f3c5c297dbc81 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sqlphilosophy-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sqlphilosophy-0.2.0-py3-none-any.whl
- Upload date:
- Size: 33.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d25e01291188d66a3c3ce15750267be4af5032507501f0abab0746502454314a
|
|
| MD5 |
7d40961242f590fb33ca7e86a59eb9c3
|
|
| BLAKE2b-256 |
7f22d4d8f4a6007935070027330326603cd1e7f782dc8b1237386b7c2f6acf63
|
Provenance
The following attestation bundles were made for sqlphilosophy-0.2.0-py3-none-any.whl:
Publisher:
ci.yml on SignalSafeSoftware/sqlphilosophy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sqlphilosophy-0.2.0-py3-none-any.whl -
Subject digest:
d25e01291188d66a3c3ce15750267be4af5032507501f0abab0746502454314a - Sigstore transparency entry: 2135052683
- Sigstore integration time:
-
Permalink:
SignalSafeSoftware/sqlphilosophy@7cce2c2f5ec7e57517a0b806145f3c5c297dbc81 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/SignalSafeSoftware
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@7cce2c2f5ec7e57517a0b806145f3c5c297dbc81 -
Trigger Event:
push
-
Statement type: