home / skills / martinffx / claude-code-atelier / atelier-python-sqlalchemy

This skill helps you implement robust Python database access with SQLAlchemy ORM patterns, including models, sessions, queries, upserts, and JSON columns.

npx playbooks add skill martinffx/claude-code-atelier --skill atelier-python-sqlalchemy

Review the files below or copy the command above to add this skill to your agents.

Files (4)
SKILL.md
2.7 KB
---
name: python:sqlalchemy
description: SQLAlchemy ORM patterns for Python database access. Use when defining models, writing queries, implementing upserts, working with JSON columns, or managing database sessions.
user-invocable: false
---

# SQLAlchemy ORM Patterns

Modern SQLAlchemy 2.0+ patterns for database access in Python applications.

## Model Definition

```python
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy import String
from uuid import UUID
from decimal import Decimal

class Base(DeclarativeBase):
    pass

class ProductModel(Base):
    __tablename__ = "products"

    id: Mapped[UUID] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(100))
    price: Mapped[Decimal]
    in_stock: Mapped[bool] = mapped_column(default=True)
```

## Session Management

```python
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine("postgresql://user:pass@localhost/db")
SessionLocal = sessionmaker(bind=engine)

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()
```

## Query Patterns

```python
# Select
stmt = select(ProductModel).where(ProductModel.price > 100)
products = session.execute(stmt).scalars().all()

# Filter
products = session.query(ProductModel).filter(ProductModel.in_stock == True).all()

# Get by ID
product = session.get(ProductModel, product_id)

# Count
count = session.query(ProductModel).count()
```

## Upsert

```python
from sqlalchemy.dialects.postgresql import insert

stmt = insert(ProductModel).values(
    id=product_id,
    name="Widget",
    price=9.99,
)

# On conflict, update
stmt = stmt.on_conflict_do_update(
    index_elements=["id"],
    set_={"name": stmt.excluded.name, "price": stmt.excluded.price},
)

session.execute(stmt)
session.commit()
```

## Relationships

```python
from sqlalchemy.orm import relationship

class UserModel(Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    orders: Mapped[list["OrderModel"]] = relationship(back_populates="user")

class OrderModel(Base):
    __tablename__ = "orders"
    id: Mapped[int] = mapped_column(primary_key=True)
    user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
    user: Mapped["UserModel"] = relationship(back_populates="orders")
```

## JSON Columns

```python
from sqlalchemy import JSON

class ConfigModel(Base):
    __tablename__ = "configs"
    id: Mapped[int] = mapped_column(primary_key=True)
    settings: Mapped[dict] = mapped_column(JSON)

# Query JSON field
configs = session.query(ConfigModel).filter(
    ConfigModel.settings["theme"] == "dark"
).all()
```

See references/ for model patterns, query optimization, and async SQLAlchemy.

Overview

This skill provides modern SQLAlchemy 2.0+ ORM patterns for Python database access, focused on model definition, querying, session management, relationships, JSON columns, and upserts. It presents practical code patterns to define typed models, run efficient queries, and perform conflict-safe inserts for PostgreSQL. The goal is to standardize common database tasks with clear, maintainable examples.

How this skill works

The skill shows typed DeclarativeBase models with Mapped annotations and mapped_column helpers to create safe, self-documenting schemas. It demonstrates sessionmaker-based session lifecycle management for synchronous code, common query patterns (select, filter, get, count), and relationship wiring with back_populates. For PostgreSQL it includes dialect-specific upsert via insert().on_conflict_do_update and JSON column querying using the JSON type.

When to use it

  • Defining typed models with SQLAlchemy 2.0+ and Python type hints
  • Implementing CRUD operations and efficient query patterns
  • Managing session lifecycle in web apps or scripts
  • Performing PostgreSQL upserts (conflict-safe inserts/updates)
  • Modeling and querying JSON columns and nested data

Best practices

  • Use DeclarativeBase with Mapped and mapped_column to keep models type-checked and IDE-friendly
  • Create a single sessionmaker (SessionLocal) and always close sessions in finally blocks or dependency-managed contexts
  • Prefer select() with session.execute(...).scalars() for modern, explicit queries instead of legacy query() when possible
  • Use dialect-specific constructs (e.g., postgresql.insert().on_conflict_do_update) only where the backend supports them
  • Define relationships with back_populates and explicit ForeignKey references to keep bi-directional navigation clear

Example use cases

  • Define Product, User, Order, and Config models with typed fields and defaults for a commerce app
  • Query all in-stock products or count records for metrics and pagination
  • Perform an upsert for product inventory to atomically insert or update on id conflict
  • Store user preferences in a JSON column and filter rows by nested keys (e.g., settings['theme'] == 'dark')
  • Wire user→orders relationships so ORMs can load and persist cascaded changes easily

FAQ

Can these patterns be used with async SQLAlchemy?

Yes. The patterns map to async usage but require AsyncEngine, async_sessionmaker, and async methods like session.execute/commit; model definitions remain the same.

Are upserts portable across databases?

The shown upsert uses PostgreSQL-specific on_conflict_do_update. For other backends use their native upsert features or emulate with transactions.

How should I handle sessions in web frameworks?

Provide a session-per-request via framework dependency injection or middleware, ensuring the session is committed or rolled back and closed at the end of each request.