Skip to main content

Use SQLAlchemy in a Pythonic way.

Project description

sqlalchemy-crud-tx

English | 中文

A lightweight CRUD + transaction helper for SQLAlchemy:

  • Context-managed CRUD with nested savepoints: with CRUD(Model) as crud:
  • Function-level transactions via @CRUD.transaction() with join semantics
  • Configurable error policy (error_policy="raise"|"status_only") and pluggable logger
  • SQLAlchemy 2.x typed query helpers (select/execute/scalars/scalar)

Install

pip install sqlalchemy-crud-tx
# or local editable install
pip install -e .

Requires Python 3.11+ with sqlalchemy>=2.0.

Quick Start (pure SQLAlchemy)

from sqlalchemy import String, Integer, create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, sessionmaker
from sqlalchemy_crud_tx import CRUD

engine = create_engine("sqlite:///./crud_example.db", echo=False)
SessionLocal = sessionmaker(bind=engine, expire_on_commit=False)


class Base(DeclarativeBase):
    pass


class User(Base):
    __tablename__ = "example_user"
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False)


Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)

CRUD.configure(session_provider=SessionLocal, error_policy="raise")

with CRUD(User) as crud:
    user = crud.add(email="demo@example.com")
    print("created", user)

with CRUD(User, email="demo@example.com") as crud:
    row = crud.first()
    print("fetched", row)

with CRUD(User) as crud:
    updated = crud.update(row, email="updated@example.com")
    print("updated", updated)

with CRUD(User, email="updated@example.com") as crud:
    crud.delete()

SQLAlchemy 2.x Typed Queries

from sqlalchemy import select, func

with CRUD(User, email="demo@example.com") as crud:
    # Build Select from CRUD defaults
    stmt = crud.select().order_by(User.id)
    users = crud.scalars(stmt).all()  # list[User]

    # Project columns -> row objects (not ORM model instances)
    rows = crud.execute(crud.select(User.id, User.email)).all()
    first_email = rows[0].email

    # Scalar helper
    total = crud.scalar(select(func.count(User.id)))

2.0 Breaking Changes

Legacy Query-based APIs were removed in 2.0.0:

  • CRUD.query() removed
  • CRUDQuery removed
  • configure(query_builder=...) removed
  • Built-in paginate(...) removed

Migration quick map:

Before After
crud.query().all() crud.all() or crud.scalars(crud.select()).all()
crud.query().filter(...).first() crud.first(crud.select().where(...))
crud.query().with_entities(User.id, User.email).all() crud.execute(crud.select(User.id, User.email)).all()
crud.query().order_by(...).paginate(...) explicit count + limit + offset in user code

Typing notes:

  • Runtime row attribute access like row.email may work.
  • Static hard guarantee is based on tuple-position types (row[0], row[1]).

Function-Level Transactions

from sqlalchemy_crud_tx import CRUD

CRUD.configure(session_provider=SessionLocal, error_policy="raise")

@CRUD.transaction(error_policy="raise")
def create_two_users():
    with CRUD(User) as crud1:
        crud1.add(email="a@example.com")
    with CRUD(User) as crud2:
        crud2.add(email="b@example.com")

create_two_users()
  • The outermost call commits or rolls back; inner CRUD contexts only mark status when exceptions occur.
  • With error_policy="status_only", SQLAlchemyError is rolled back and caught; check crud.status / crud.error instead.

Docs & Examples

  • Full example: docs/examples/basic_crud.py
  • Transaction refactor notes/TODO: docs/crud_refactor_todo.md
  • Typing directions: docs/todo.md

Testing

  1. Provide a DB URI via env or .env: TEST_DB=sqlite:///./test.db (or another driver).
  2. Install test deps, then:
    pytest -q
    

Notes

  • Always call CRUD.configure(session_provider=...) before using CRUD instances.
  • Type checking baseline is defined by Pylance/Pyright strict (pyrightconfig.json).
  • If a Session may already be in a transaction (for example, AUTOBEGIN after expire_on_commit), set existing_txn_policy in CRUD.configure(...) to control behaviour (error, join, savepoint, adopt_autobegin, reset).

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

sqlalchemy_crud_tx-2.0.1.tar.gz (21.5 kB view details)

Uploaded Source

Built Distribution

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

sqlalchemy_crud_tx-2.0.1-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file sqlalchemy_crud_tx-2.0.1.tar.gz.

File metadata

  • Download URL: sqlalchemy_crud_tx-2.0.1.tar.gz
  • Upload date:
  • Size: 21.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sqlalchemy_crud_tx-2.0.1.tar.gz
Algorithm Hash digest
SHA256 c4a3ac7de327ae2e6bf872be3331adc5624379b7677884ff15228d6742bd0686
MD5 923eb594c8f5e08ba67804b8e3022cea
BLAKE2b-256 b1afafbde5ee9904bae9ebe6fefdae341a3a6bc5e19992fd0e6fa2994ab5caf1

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlalchemy_crud_tx-2.0.1.tar.gz:

Publisher: publish-pypi.yml on ZM-Kimu/sqlalchemy-crud-tx

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

File details

Details for the file sqlalchemy_crud_tx-2.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for sqlalchemy_crud_tx-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 28e900b99d2ac656927b474430ce0747dcf6c050f8d3aca330ee7804e8b04d55
MD5 ee58abcc260a0da7a4f3db83097f32a0
BLAKE2b-256 5b437258c3b88ea6c2f5bddd25b0cfeb8f1da59364f629166958d7b837ead6b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlalchemy_crud_tx-2.0.1-py3-none-any.whl:

Publisher: publish-pypi.yml on ZM-Kimu/sqlalchemy-crud-tx

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