Install any skill in seconds. Free to start, no credit card required.
Get Started Free →SQLAlchemy and database patterns for Python. Triggers on: sqlalchemy, database, orm, migration, alembic, async database, connection pool, repository pattern, unit of work.
.claude/skills/aiskillstore-python-database-patterns/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 47% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 327% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 31% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 134% | 0% |
SQLAlchemy 2.0 and database best practices.
pythonfrom 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()
pythonfrom 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()
pythonfrom 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")
pythonfrom 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))
pythonfrom 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
| 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)) |
./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/alembic.ini.template - Alembic configuration templatePrerequisites:
python-typing-patterns - Mapped types and annotationspython-async-patterns - Async database sessionsRelated Skills:
python-fastapi-patterns - Dependency injection for DB sessionspython-pytest-patterns - Database fixtures and testing| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 3,895 | 3,113 | -20% | 1 | 1 | 0% | 671 | 1,795 | +168% | 0 | 0 | — |
case-02 | pass→pass | 12,894 | 8,386 | -35% | 1 | 1 | 0% | 2,470 | 2,764 | +12% | 0 | 0 | — |
case-03 | pass→pass | 5,710 | 4,754 | -17% | 1 | 1 | 0% | 905 | 2,178 | +141% | 0 | 0 | — |
case-04 | pass→pass | 10,582 | 6,430 | -39% | 1 | 1 | 0% | 1,816 | 2,467 | +36% | 0 | 0 | — |
case-05 | pass→pass | 9,923 | 5,434 | -45% | 1 | 1 | 0% | 1,712 | 2,232 | +30% | 0 | 0 | — |
case-06 | pass→pass | 8,018 | 6,159 | -23% | 1 | 1 | 0% | 1,422 | 2,467 | +73% | 0 | 0 | — |
case-07 | pass→pass | 10,398 | 5,035 | -52% | 1 | 1 | 0% | 2,051 | 2,259 | +10% | 0 | 0 | — |
case-08 | pass→pass | 7,357 | 2,982 | -59% | 1 | 1 | 0% | 1,278 | 1,771 | +39% | 0 | 0 | — |
case-09 | fail→pass | 8,927 | 2,641 | -70% | 1 | 1 | 0% | 975 | 1,783 | +83% | 0 | 0 | — |
case-10 | fail→pass | 7,900 | 4,384 | -45% | 1 | 1 | 0% | 1,424 | 2,094 | +47% | 0 | 0 | — |
case-11 | fail→pass | 3,071 | 3,997 | +30% | 1 | 1 | 0% | 464 | 1,979 | +327% | 0 | 0 | — |
case-12 | pass→pass | 7,856 | 2,921 | -63% | 1 | 1 | 0% | 1,386 | 1,765 | +27% | 0 | 0 | — |
case-13 | pass→pass | 4,728 | 4,034 | -15% | 1 | 1 | 0% | 809 | 1,915 | +137% | 0 | 0 | — |
case-14 | fail→pass | 9,568 | 4,990 | -48% | 1 | 1 | 0% | 1,657 | 2,166 | +31% | 0 | 0 | — |
case-15 | pass→pass | 8,602 | 6,906 | -20% | 1 | 1 | 0% | 1,598 | 2,575 | +61% | 0 | 0 | — |
case-16 | fail→pass | 4,776 | 3,530 | -26% | 1 | 1 | 0% | 806 | 1,887 | +134% | 0 | 0 | — |
case-17 | fail→pass | 6,465 | 5,459 | -16% | 1 | 1 | 0% | 1,099 | 2,259 | +106% | 0 | 0 | — |
case-18 | pass→pass | 9,984 | 4,048 | -59% | 1 | 1 | 0% | 1,741 | 1,996 | +15% | 0 | 0 | — |
case-19 | pass→pass | 7,207 | 6,131 | -15% | 1 | 1 | 0% | 1,131 | 2,323 | +105% | 0 | 0 | — |
case-20 | pass→pass | 5,797 | 4,245 | -27% | 1 | 1 | 0% | 715 | 1,975 | +176% | 0 | 0 | — |
case-21 | pass→pass | 3,716 | 3,086 | -17% | 1 | 1 | 0% | 610 | 1,818 | +198% | 0 | 0 | — |
case-22 | pass→pass | 2,542 | 2,954 | +16% | 1 | 1 | 0% | 359 | 1,628 | +353% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.