sqlalchemy-orm
cohen-liel/hivemind/.claude/skills/sqlalchemy-orm/SKILL.md
SQLAlchemy 2.0 async ORM patterns. Use when defining models, relationships, queries, or migrations with SQLAlchemy in Python.
Skill108 starsChanged 7 months ago
What's in it
- SQLAlchemy 2.0 Async ORM Patterns
- Database Setup
- Model Pattern
- CRUD Patterns
- Rules
---
name: sqlalchemy-orm
description: SQLAlchemy 2.0 async ORM patterns. Use when defining models, relationships, queries, or migrations with SQLAlchemy in Python.
---
# SQLAlchemy 2.0 Async ORM Patterns
## Database Setup
```python
# database.py
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase
engine = create_async_engine(
settings.DATABASE_URL, # postgresql+asyncpg://user:pass@host/db
pool_size=10,
max_overflow=20,
pool_pre_ping=True, # Verify connection before use
echo=settings.DEBUG,
)
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
class Base(DeclarativeBase):
pass
```
## Model Pattern
```python
from sqlalchemy import String, ForeignKey, func, text
from sqlalchemy.orm import Mapped, mapped_column, relationship
class TimestampMixin:
created_at: Mapped[datetime] = mapped_column(
server_default=func.now(), nullable=False
)
updated_at: Mapped[datetime] = mapped_column(
server_default=func.now(), onupdate=func.now(), nullable=False
)
class User(Base, TimestampMixin):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False, index=True)
name: Mapped[str] = mapped_column(String(100), nullable=False)
hashed_password: Mapped[str] = mapped_column(nullable=False)
is_active: Mapped[bool] = mapped_column(default=True, server_default=text("true"))
# Relationship
posts: Mapped[list["Post"]] = relationship("Post", back_populates="author", lazy="select")
class Post(Base, TimestampMixin):
__tablename__ = "posts"
id: Mapped[int] = mapped_column(primary_key=True)
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, index=True)
title: Mapped[str] = mapped_column(String(255), nullable=False)
body: Mapped[str] = mapped_column(nullable=False)
author: Mapped["User"] = relationship("User", back_populates="posts")
```
## CRUD Patterns
```python
# SELECT with filter
async def get_user(db: AsyncSession, user_id: int) -> User | None:
return await db.get(User, user_id)
async def get_user_by_email(db: AsyncSession, email: str) -> User | None:
result = await db.execute(select(User).where(User.email == email))
return result.scalar_one_or_none()
# SELECT with join (avoid N+1)
async def get_posts_with_authors(db: AsyncSession) -> list[Post]:
result = await db.execute(
select(Post).options(selectinload(Post.author)).order_by(Post.created_at.desc())
)
return list(result.scalars())
# INSERT
async def create_user(db: AsyncSession, data: UserCreate) -> User:
user = User(**data.model_dump())
db.add(user)
await db.flush() # Get ID without committing
await db.refresh(user)
return user
# UPDATE
async def update_user(db: AsyncSession, user_id: int, data: dict) -> User:
await db.execute(update(User).where(User.id == user_id).values(**data))
return await get_user(db, user_id)
# Bulk insert
async def bulk_create_posts(db: AsyncSession, posts: list[dict]):
await db.execute(insert(Post), posts)
```
## Rules
- Use `selectinload()` or `joinedload()` for relationships — never lazy load in async
- Use `expire_on_commit=False` in async sessions
- `flush()` to get IDs mid-transaction, `commit()` only at end of request
- Rollback on exception (handled by Depends(get_db))
- Use `mapped_column()` not `Column()` (SQLAlchemy 2.0 style)
- Add `index=True` on all ForeignKeys and frequently filtered columns
- `pool_pre_ping=True` to handle connection drops
More agent context in cohen-liel/hivemind
75 other files this repository gives its agents, the first 60 shown.
CLAUDE.md
Skill
- algorithmic-art.claude/skills/algorithmic-art/SKILL.md
- api-design.claude/skills/api-design/SKILL.md
- apple-notes.claude/skills/apple-notes/SKILL.md
- apple-reminders.claude/skills/apple-reminders/SKILL.md
- article-writing.claude/skills/article-writing/SKILL.md
- async-python.claude/skills/async-python/SKILL.md
- brand-guidelines.claude/skills/brand-guidelines/SKILL.md
- camsnap.claude/skills/camsnap/SKILL.md
- canvas-design.claude/skills/canvas-design/SKILL.md
- celery-tasks.claude/skills/celery-tasks/SKILL.md
- claude-api.claude/skills/claude-api/SKILL.md
- coding-agent.claude/skills/coding-agent/SKILL.md
- content-engine.claude/skills/content-engine/SKILL.md
- diffs.claude/skills/diffs/SKILL.md
- doc-coauthoring.claude/skills/doc-coauthoring/SKILL.md
- docker-deployment.claude/skills/docker-deployment/SKILL.md
- docx.claude/skills/docx/SKILL.md
- e2e-testing.claude/skills/e2e-testing/SKILL.md
- email-service.claude/skills/email-service/SKILL.md
- fastapi-backend.claude/skills/fastapi-backend/SKILL.md
- frontend-design.claude/skills/frontend-design/SKILL.md
- frontend-slides.claude/skills/frontend-slides/SKILL.md
- gh-issues.claude/skills/gh-issues/SKILL.md
- github.claude/skills/github/SKILL.md
- git-workflow.claude/skills/git-workflow/SKILL.md
- graphql-api.claude/skills/graphql-api/SKILL.md
- healthcheck.claude/skills/healthcheck/SKILL.md
- internal-comms.claude/skills/internal-comms/SKILL.md
- investor-materials.claude/skills/investor-materials/SKILL.md
- jwt-authentication.claude/skills/jwt-authentication/SKILL.md
- market-research.claude/skills/market-research/SKILL.md
- mcp-builder.claude/skills/mcp-builder/SKILL.md
- mermaid-diagrams.claude/skills/mermaid-diagrams/SKILL.md
- microservices.claude/skills/microservices/SKILL.md
- mobile-react-native.claude/skills/mobile-react-native/SKILL.md
- model-usage.claude/skills/model-usage/SKILL.md
- nextjs-fullstack.claude/skills/nextjs-fullstack/SKILL.md
- nodejs-express.claude/skills/nodejs-express/SKILL.md
- obsidian.claude/skills/obsidian/SKILL.md
- openai-whisper.claude/skills/openai-whisper/SKILL.md
- oracle.claude/skills/oracle/SKILL.md
- pdf.claude/skills/pdf/SKILL.md
- peekaboo.claude/skills/peekaboo/SKILL.md
- planning-with-files.claude/skills/planning-with-files/SKILL.md
- postgres-database.claude/skills/postgres-database/SKILL.md
- pptx.claude/skills/pptx/SKILL.md
- prisma-orm.claude/skills/prisma-orm/SKILL.md
- prose.claude/skills/prose/SKILL.md
- pytest-patterns.claude/skills/pytest-patterns/SKILL.md
- react-typescript.claude/skills/react-typescript/SKILL.md
- redis-caching.claude/skills/redis-caching/SKILL.md
- s3-file-storage.claude/skills/s3-file-storage/SKILL.md
- security-review.claude/skills/security-review/SKILL.md
- session-logs.claude/skills/session-logs/SKILL.md
- skill-creator.claude/skills/skill-creator/SKILL.md
- slack-gif-creator.claude/skills/slack-gif-creator/SKILL.md
- state-management.claude/skills/state-management/SKILL.md
- strategic-compact.claude/skills/strategic-compact/SKILL.md
- stripe-payments.claude/skills/stripe-payments/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.

