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. - Opt-in strict row decoders via
sqlphilosophy.strictfor non-coercing scalars, timestamps, enums, collections, UUIDs, and recursive JSON. - 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.strict |
Opt-in non-coercing row decoders and strict JSON validation |
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.
Metadata
Release files for sqlphilosophy 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sqlphilosophy-0.3.0.tar.gz | 29.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sqlphilosophy-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.0 kB
Release files / sqlphilosophy-0.3.0.tar.gz
| Download URL | sqlphilosophy-0.3.0.tar.gz |
|---|---|
| Size | 29.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1e466bd804c87a73c5c7a89e05101538300899ac679acac45c86bca4e4adf34
|
|
BLAKE2b-256 checksum How to use checksums |
d7e91a9fe89d6b482c7b5f8fb6ad55f715043348e1b37f95fc7f7e786be69622
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 8, 2026.
Transparency logRelease files / sqlphilosophy-0.3.0-py3-none-any.whl
| Download URL | sqlphilosophy-0.3.0-py3-none-any.whl |
|---|---|
| Size | 34.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2bb208121d7993bf903db64deda915627780b7644878abc721d7b2348900e2a2
|
|
BLAKE2b-256 checksum How to use checksums |
5c46f30d5e0455ff1c79685235092ad698a4833ffbc112a6185d6cf5ee8b1073
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 8, 2026.
Transparency logSecurity for sqlphilosophy 0.3.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for sqlphilosophy-0.3.0.tar.gz
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 Sep 8, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.