Skip to main content

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; requires batch_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

This repo uses uv and Ruff:

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


Download files

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

Source Distribution

sqlphilosophy-0.2.0.tar.gz (28.6 kB view details)

Uploaded Source

Built Distribution

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

sqlphilosophy-0.2.0-py3-none-any.whl (33.1 kB view details)

Uploaded Python 3

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

Hashes for sqlphilosophy-0.2.0.tar.gz
Algorithm Hash digest
SHA256 f383c27b52d51530cec68742cac6958f7809a47133808b5c76a185e7da3399f6
MD5 43a3357330667bf9b96d71be140273d0
BLAKE2b-256 91420b784623adc34ac3b115e6590e22af9ccfe0b702a2551097ffdb787cac77

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlphilosophy-0.2.0.tar.gz:

Publisher: ci.yml on SignalSafeSoftware/sqlphilosophy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for sqlphilosophy-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d25e01291188d66a3c3ce15750267be4af5032507501f0abab0746502454314a
MD5 7d40961242f590fb33ca7e86a59eb9c3
BLAKE2b-256 7f22d4d8f4a6007935070027330326603cd1e7f782dc8b1237386b7c2f6acf63

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlphilosophy-0.2.0-py3-none-any.whl:

Publisher: ci.yml on SignalSafeSoftware/sqlphilosophy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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