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
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.1.9.tar.gz (28.2 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.1.9-py3-none-any.whl (32.7 kB view details)

Uploaded Python 3

File details

Details for the file sqlphilosophy-0.1.9.tar.gz.

File metadata

  • Download URL: sqlphilosophy-0.1.9.tar.gz
  • Upload date:
  • Size: 28.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for sqlphilosophy-0.1.9.tar.gz
Algorithm Hash digest
SHA256 16b9ffa29727458b6abdc7c1ee26f20737c80c318d0a7605014e3fa63e384428
MD5 cb03b864564f3238ea2e5a3b9cb6b7e1
BLAKE2b-256 5f0635b56b6b8dae949792287c654d49a7c88fd93e386897474e6776e4a36603

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlphilosophy-0.1.9.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.1.9-py3-none-any.whl.

File metadata

  • Download URL: sqlphilosophy-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 32.7 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.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 1a21eddd486a08fbc092d5645173a3bca99b6b971cebcd6454d8748678ccde9d
MD5 13d52fbfbe49480cd6d4aea3886f2446
BLAKE2b-256 a6de0e03b449f72fde35b33971e986bc23a6ec2888f3e9b18b9a03ed4fdba2f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlphilosophy-0.1.9-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