Automated summary
This skill provides SQLAlchemy 2.0 patterns for Python, covering typed declarative models, queries, relationships, async sessions, and FastAPI integration.
Strengths
- Demonstrates SQLAlchemy 2.0 syntax with Mapped and mapped_column annotations
- Explains async setup using create_async_engine and async_sessionmaker
- Shows one-to-many and many-to-one relationships with back_populates
- Includes concrete FastAPI dependency-injection examples
Limitations
- Does not detail Alembic migrations despite mentioning them in triggers
- Assumes SQLAlchemy 2.0+ and Python 3.10+, with asyncpg or aiosqlite for async
- Repository and unit-of-work patterns are named but barely covered
Use when writing or reviewing Python code with SQLAlchemy 2.0, especially models, queries, or async sessions.
Avoid for advanced Alembic migrations or non-relational databases, which this skill does not cover.
Security analysis
SafeThe skill is an educational SQLAlchemy reference. It contains no destructive commands, exfiltration instructions, obfuscated payloads, or attempts to disable safety controls. The Bash tool is declared but the content does not instruct running unsafe shell commands. Example connection strings use placeholder credentials, not real secrets.
No concerns found
How this analysis is madeExamples
Set up an async SQLAlchemy 2.0 engine and session factory for a PostgreSQL app, with a select query for active users.Create SQLAlchemy 2.0 User and Post models with a one-to-many relationship and typed Mapped annotations.Add a FastAPI dependency that yields an AsyncSession and use it to fetch a user by ID with a 404 fallback.name: python-database-patterns description: "SQLAlchemy and database patterns for Python. Triggers on: sqlalchemy, database, orm, migration, alembic, async database, connection pool, repository pattern, unit of work." compatibility: "SQLAlchemy 2.0+, Python 3.10+. Async requires asyncpg (PostgreSQL) or aiosqlite." allowed-tools: "Read Write Bash" depends-on: [python-typing-patterns, python-async-patterns] related-skills: [python-fastapi-patterns]
Python Database Patterns
SQLAlchemy 2.0 and database best practices.
SQLAlchemy 2.0 Basics
from sqlalchemy import create_engine, select
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(100))
email: Mapped[str] = mapped_column(String(255), unique=True)
is_active: Mapped[bool] = mapped_column(default=True)
# Create engine and tables
engine = create_engine("postgresql://user:pass@localhost/db")
Base.metadata.create_all(engine)
# Query with 2.0 style
with Session(engine) as session:
stmt = select(User).where(User.is_active == True)
users = session.execute(stmt).scalars().all()
Async SQLAlchemy
from sqlalchemy.ext.asyncio import (
AsyncSession,
async_sessionmaker,
create_async_engine,
)
from sqlalchemy import select
# Async engine
engine = create_async_engine(
"postgresql+asyncpg://user:pass@localhost/db",
echo=False,
pool_size=5,
max_overflow=10,
)
# Session factory
async_session = async_sessionmaker(engine, expire_on_commit=False)
# Usage
async with async_session() as session:
result = await session.execute(select(User).where(User.id == 1))
user = result.scalar_one_or_none()
Model Relationships
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, Mapped, mapped_column
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
# One-to-many
posts: Mapped[list["Post"]] = relationship(back_populates="author")
class Post(Base):
__tablename__ = "posts"
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
author_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
# Many-to-one
author: Mapped["User"] = relationship(back_populates="posts")
Common Query Patterns
from sqlalchemy import select, and_, or_, func
# Basic select
stmt = select(User).where(User.is_active == True)
# Multiple conditions
stmt = select(User).where(
and_(
User.is_active == True,
User.age >= 18
)
)
# OR conditions
stmt = select(User).where(
or_(User.role == "admin", User.role == "moderator")
)
# Ordering and limiting
stmt = select(User).order_by(User.created_at.desc()).limit(10)
# Aggregates
stmt = select(func.count(User.id)).where(User.is_active == True)
# Joins
stmt = select(User, Post).join(Post, User.id == Post.author_id)
# Eager loading
from sqlalchemy.orm import selectinload
stmt = select(User).options(selectinload(User.posts))
FastAPI Integration
from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Annotated
async def get_db() -> AsyncGenerator[AsyncSession, None]:
async with async_session() as session:
yield session
DB = Annotated[AsyncSession, Depends(get_db)]
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: DB):
result = await db.execute(select(User).where(User.id == user_id))
user = result.scalar_one_or_none()
if not user:
raise HTTPException(status_code=404)
return user
Quick Reference
| Operation | SQLAlchemy 2.0 Style |
|-----------|---------------------|
| Select all | select(User) |
| Filter | .where(User.id == 1) |
| First | .scalar_one_or_none() |
| All | .scalars().all() |
| Count | select(func.count(User.id)) |
| Join | .join(Post) |
| Eager load | .options(selectinload(User.posts)) |
Additional Resources
./references/sqlalchemy-async.md- Async patterns, session management./references/connection-pooling.md- Pool configuration, health checks./references/transactions.md- Transaction patterns, isolation levels./references/migrations.md- Alembic setup, migration strategies
Assets
./assets/alembic.ini.template- Alembic configuration template
See Also
Prerequisites:
python-typing-patterns- Mapped types and annotationspython-async-patterns- Async database sessions
Related Skills:
python-fastapi-patterns- Dependency injection for DB sessionspython-pytest-patterns- Database fixtures and testing
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/python-database-patterns-mmbizjsl/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/python-database-patterns-mmbizjsl' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/python-database-patterns-mmbizjsl/download' --output '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md.part' && mv '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md.part' '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Environment declared by the author: SQLAlchemy 2.0+, Python 3.10+. Async requires asyncpg (PostgreSQL) or aiosqlite.
Tools declared by the author (check availability in your agent): Read Write Bash
Original excerpt: Quick Reference
| Operation | SQLAlchemy 2.0 Style |
|---|---|
| Select all | select(User) |
| Filter | .where(User.id == 1) |
| First | .scalar_one_or_none() |
| All | .scalars().all() |
| Count | select(func.count(User.id)) |
| Join | .join(Post) |
| Eager load | .options(selectinload(User.posts)) |
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md' && test -s '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/python-database-patterns' && cp -R '.skill-downloads/python-database-patterns-mmbizjsl' '.claude/skills/python-database-patterns'Cursor
test -f '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md' && test -s '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/python-database-patterns' && cp -R '.skill-downloads/python-database-patterns-mmbizjsl' '.cursor/skills/python-database-patterns'Codex
test -f '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md' && test -s '.skill-downloads/python-database-patterns-mmbizjsl/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/python-database-patterns' && cp -R '.skill-downloads/python-database-patterns-mmbizjsl' '.agents/skills/python-database-patterns'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/python-database-patterns-mmbizjsl'openskills read 'python-database-patterns-mmbizjsl'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/python-database-patterns-mmbizjsl/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.