Change Database Schema
martin-ueding/geo-activity-playground
How to change the SQLAlchemy data model and generate the matching Alembic migration.
A skill your agent uses when using async SQLAlchemy 2.0 — defining models, writing queries, managing async sessions, loading relationships without N+1, or setting up and debugging Alembic migrations.
$ npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install kid-sid/claude-spellbook sqlalchemy --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/sqlalchemy .claude/skills/sqlalchemy && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "sqlalchemy" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemy into .claude/skills/sqlalchemy/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sqlalchemy", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemyType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install kid-sid/claude-spellbook sqlalchemy --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/sqlalchemy .agents/skills/sqlalchemy && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "sqlalchemy" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemy into .agents/skills/sqlalchemy/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sqlalchemy", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install kid-sid/claude-spellbook sqlalchemy --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/sqlalchemy .cursor/skills/sqlalchemy && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "sqlalchemy" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemy into .cursor/skills/sqlalchemy/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sqlalchemy", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/kid-sid/claude-spellbook.git --path skills/sqlalchemy--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install kid-sid/claude-spellbook sqlalchemy --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/sqlalchemy .gemini/skills/sqlalchemy && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "sqlalchemy" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemy into .gemini/skills/sqlalchemy/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sqlalchemy", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install kid-sid/claude-spellbook sqlalchemyInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/sqlalchemy .github/skills/sqlalchemy && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "sqlalchemy" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemy into .github/skills/sqlalchemy/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sqlalchemy", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install kid-sid/claude-spellbook sqlalchemy --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/sqlalchemy .opencode/skills/sqlalchemy && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "sqlalchemy" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/sqlalchemy into .opencode/skills/sqlalchemy/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "sqlalchemy", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
sqlalchemyA skill your agent uses when using async SQLAlchemy 2.0 — defining models, writing queries, managing async sessions, loading relationships without N+1, or setting up and debugging Alembic migrations.
Sqlalchemy is an agent skill from kid-sid/claude-spellbook. Use when using async SQLAlchemy 2.0 — defining models, writing queries, managing async sessions, loading relationships without N+1, or setting up and debugging Alembic migrations.
Its SKILL.md is about 3.5k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Databases, covering ORMs and data access and Database migrations. It works with SQLAlchemy. The repository describes itself as: A curated collection of skills, prompts, and workflows that extend Claude's capabilities — your personal grimoire for AI-powered development. The licence is MIT.
Read from SKILL.md and the folder at commit a7c2ac9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
makeFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Sqlalchemy loads about 3.5k tokens when it runs. Until then it costs about 48 tokens; SKILL.md has 493 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from kid-sid/claude-spellbook at commit a7c2ac9, republished under its MIT licence (© kid-sid). 493 words, ~3,455 tokens.
.claude/skills/sqlalchemy/SKILL.md (or your agent's skills folder).Modern SQLAlchemy 2.0 with full async support (asyncpg) and Alembic migrations.
Mapped / mapped_columnselect, join, filter, order_by)AsyncSession, async_sessionmaker)selectin, joined, lazy)from datetime import datetime
from uuid import UUID, uuid4
from sqlalchemy import String, ForeignKey, Text, TIMESTAMP, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.dialects.postgresql import UUID as PGUUID, JSONB
class Base(DeclarativeBase):
pass
class UserORM(Base):
__tablename__ = "users"
id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
email: Mapped[str] = mapped_column(String(255), unique=True, nullable=False, index=True)
name: Mapped[str] = mapped_column(String(255), nullable=False)
role: Mapped[str] = mapped_column(String(50), nullable=False, default="user")
metadata_: Mapped[dict] = mapped_column("metadata", JSONB, nullable=False, default=dict)
created_at: Mapped[datetime] = mapped_column(
TIMESTAMP(timezone=True), server_default=func.now(), nullable=False
)
updated_at: Mapped[datetime] = mapped_column(
TIMESTAMP(timezone=True), server_default=func.now(), onupdate=func.now()
)
# Relationship — loads orders when accessed
orders: Mapped[list["OrderORM"]] = relationship("OrderORM", back_populates="user")
class OrderORM(Base):
__tablename__ = "orders"
id: Mapped[UUID] = mapped_column(PGUUID(as_uuid=True), primary_key=True, default=uuid4)
user_id: Mapped[UUID] = mapped_column(
PGUUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
)
status: Mapped[str] = mapped_column(String(50), nullable=False, default="pending")
total: Mapped[float] = mapped_column(nullable=False)
created_at: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=True), server_default=func.now())
user: Mapped["UserORM"] = relationship("UserORM", back_populates="orders")Key rules:
Mapped[T] declares the Python type; mapped_column() declares the column confignullable=False is explicit — Mapped[str] without it is still nullable in older versionsPGUUID(as_uuid=True) so SQLAlchemy returns Python UUID objects, not stringsindex=True on FK columns — always# config/database.py
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
# asyncpg driver — fastest PostgreSQL async driver
engine = create_async_engine(
"postgresql+asyncpg://user:pass@localhost:5432/mydb",
pool_size=10, # max persistent connections
max_overflow=20, # extra connections above pool_size under load
pool_pre_ping=True, # test connections before use (handles dropped connections)
echo=False, # set True to log all SQL (dev only)
)
# Session factory — reuse this, don't recreate per request
AsyncSessionLocal = async_sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False, # keep attributes accessible after commit
autoflush=False,
)# api/dependencies.py
from sqlalchemy.ext.asyncio import AsyncSession
from config.database import AsyncSessionLocal
async def get_db() -> AsyncSession:
async with AsyncSessionLocal() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raiseFastAPI caches this dependency within a request — one session per request.
from sqlalchemy import select, update, delete
from sqlalchemy.ext.asyncio import AsyncSession
class UserCRUD:
def __init__(self, session: AsyncSession):
self.session = session
async def get(self, user_id: UUID) -> UserORM | None:
result = await self.session.execute(
select(UserORM).where(UserORM.id == user_id)
)
return result.scalar_one_or_none()
async def get_by_email(self, email: str) -> UserORM | None:
result = await self.session.execute(
select(UserORM).where(UserORM.email == email)
)
return result.scalar_one_or_none()
async def list(self, skip: int = 0, limit: int = 100) -> list[UserORM]:
result = await self.session.execute(
select(UserORM).order_by(UserORM.created_at.desc()).offset(skip).limit(limit)
)
return list(result.scalars().all())
async def create(self, email: str, name: str, role: str = "user") -> UserORM:
user = UserORM(email=email, name=name, role=role)
self.session.add(user)
await self.session.flush() # assigns ID without committing
await self.session.refresh(user)
return user
async def update(self, user_id: UUID, **kwargs) -> UserORM | None:
await self.session.execute(
update(UserORM).where(UserORM.id == user_id).values(**kwargs)
)
return await self.get(user_id)
async def delete(self, user_id: UUID) -> None:
await self.session.execute(
delete(UserORM).where(UserORM.id == user_id)
)
async def count(self, role: str | None = None) -> int:
from sqlalchemy import func
q = select(func.count()).select_from(UserORM)
if role:
q = q.where(UserORM.role == role)
result = await self.session.execute(q)
return result.scalar_one()from sqlalchemy import select, and_, or_, func
from sqlalchemy.orm import selectinload, joinedload
# JOIN — users with their order count
result = await session.execute(
select(UserORM, func.count(OrderORM.id).label("order_count"))
.outerjoin(OrderORM, UserORM.id == OrderORM.user_id)
.group_by(UserORM.id)
.order_by(func.count(OrderORM.id).desc())
)
rows = result.all() # list of (UserORM, order_count) tuples
# Relationship loading — selectinload avoids N+1
result = await session.execute(
select(UserORM)
.options(selectinload(UserORM.orders)) # one extra query for all orders
.where(UserORM.role == "admin")
)
users = result.scalars().all()
for user in users:
print(user.orders) # no extra query
# joinedload — single JOIN query (good for to-one relationships)
result = await session.execute(
select(OrderORM)
.options(joinedload(OrderORM.user))
.where(OrderORM.status == "pending")
)
orders = result.unique().scalars().all()
# Filtering with operators
result = await session.execute(
select(UserORM).where(
and_(
UserORM.role.in_(["admin", "manager"]),
UserORM.created_at > datetime(2024, 1, 1),
or_(
UserORM.name.ilike("%alice%"),
UserORM.email.ilike("%alice%"),
),
)
)
)
# JSONB filtering
result = await session.execute(
select(UserORM).where(
UserORM.metadata_["plan"].astext == "pro"
)
)| Strategy | When to use | Extra queries |
|---|---|---|
selectinload | One-to-many, loading multiple parents | 1 extra per relationship |
joinedload | Many-to-one (loading parent from child) | 0 extra (JOIN) |
lazy="raise" | Default in strict mode — force explicit loading | Raises if accessed |
lazy="noload" | Never load — when you never need the relation | 0 |
# Set default loading per model
class OrderORM(Base):
user: Mapped["UserORM"] = relationship(
"UserORM",
back_populates="orders",
lazy="raise", # must explicitly use joinedload/selectinload in queries
)# Session auto-handles transaction — commit/rollback in dependency
# Explicit savepoint (nested transaction)
async with session.begin_nested():
session.add(obj)
# rolls back to savepoint on exception, not the whole transaction
# Bulk insert (much faster than add() in a loop)
await session.execute(
UserORM.__table__.insert(),
[{"email": f"user{i}@test.com", "name": f"User {i}"} for i in range(1000)],
)
# Upsert (PostgreSQL ON CONFLICT)
from sqlalchemy.dialects.postgresql import insert
stmt = insert(UserORM).values(email="alice@example.com", name="Alice")
stmt = stmt.on_conflict_do_update(
index_elements=["email"],
set_={"name": stmt.excluded.name, "updated_at": func.now()},
)
await session.execute(stmt)# In agentex/:
alembic init alembic # creates alembic/ dir + alembic.ini
# or with make:
make migration NAME="add_users_table"
make apply-migrationsalembic/env.py — connect to async engine and point at your models:
from sqlalchemy.ext.asyncio import async_engine_from_config
from adapters.orm import Base # import your Base so models are registered
target_metadata = Base.metadata
def run_migrations_online():
connectable = async_engine_from_config(config.get_section(config.config_ini_section))
# ... standard async alembic boilerplate# Auto-generated migration — review before applying
def upgrade() -> None:
op.create_table(
"users",
sa.Column("id", pg.UUID(as_uuid=True), primary_key=True),
sa.Column("email", sa.String(255), nullable=False),
sa.Column("created_at", sa.TIMESTAMP(timezone=True), server_default=sa.text("now()")),
)
op.create_index("ix_users_email", "users", ["email"], unique=True)
def downgrade() -> None:
op.drop_table("users")
# Add column safely (large tables)
def upgrade() -> None:
# Step 1: add nullable first (no table lock)
op.add_column("orders", sa.Column("shipped_at", sa.TIMESTAMP(timezone=True), nullable=True))
# Step 2: backfill (do in batches in a separate migration or via cron)
# Step 3: add NOT NULL constraint after backfill
# Create index concurrently (no table lock)
def upgrade() -> None:
op.execute("CREATE INDEX CONCURRENTLY idx_orders_user_id ON orders(user_id)")
def downgrade() -> None:
op.execute("DROP INDEX CONCURRENTLY idx_orders_user_id")
# Data migration
def upgrade() -> None:
op.execute("UPDATE users SET role = 'member' WHERE role = 'user'")Keep ORM models separate from domain entities. Convert at the adapter boundary:
# adapters/crud_store/users.py
from domain.entities.user import User
from adapters.orm import UserORM
def convert_user_to_entity(orm: UserORM) -> User:
return User(
id=orm.id,
email=orm.email,
name=orm.name,
role=orm.role,
created_at=orm.created_at,
)
class UserRepository:
async def get(self, user_id: UUID) -> User | None:
orm = await UserCRUD(self.session).get(user_id)
return convert_user_to_entity(orm) if orm else NoneColumn() declarations — Column(String, nullable=False) without Mapped[T] loses the Python type information that mypy and editors rely on; use Mapped[str] = mapped_column(String(255), nullable=False) in all new SQLAlchemy 2.0 codeuser.orders in an async context without selectinload or joinedload raises MissingGreenlet or emits implicit lazy SQL that blocks the event loop; always declare the loading strategy in the queryAsyncSession per query — instantiating a session for each database call bypasses connection pooling and transaction batching; create one session per request via the FastAPI dependencypool_pre_ping=True — without it, connections dropped by the database (idle timeout, network reset) are handed to the application as stale; the first query fails with a connection error rather than transparently reconnectingexpire_on_commit=False missing — by default SQLAlchemy expires all attributes after commit; accessing them in an async context after the session commits triggers lazy loads that fail; set expire_on_commit=False in async_sessionmakerindex=True on foreign key columns — SQLAlchemy does not auto-index FK columns; every JOIN or filter on a FK without an index is a sequential scanUserORM in use cases or domain entities couples the business logic to the database schema; all ORM ↔ entity conversion belongs in the adapter layerMapped[T] + mapped_column() used (not old Column() style)index=Trueasync_sessionmaker with expire_on_commit=False for asyncpool_pre_ping=True on engine to handle dropped connectionsselectinload / joinedload explicit in every query that accesses a relationshipflush() used after add() to get DB-generated ID without committingCREATE INDEX CONCURRENTLY used for large tables© kid-sid, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/sqlalchemy of kid-sid/claude-spellbook.
Open the folder on GitHubat commit a7c2ac9
Sqlalchemy next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Sqlalchemy this skillkid-sid/claude-spellbook | 189 | — | ~3.5k | Automated safety check: Pass | MIT | |
| Change Database Schemamartin-ueding/geo-activity-playground | 100 | — | ~225 | Automated safety check: Pass | Custom licence | |
| Specx Sqlalchemy Migrationsmaksimzayats/specx | 202 | — | ~822 | Automated safety check: Pass | MIT | |
| Specx Add Infrastructure Adaptermaksimzayats/specx | 202 | — | ~1k | Automated safety check: Pass | MIT | |
| Python Database Patternsaiskillstore/marketplace | 430 | 1 repos | ~1.2k | Automated safety check: Notes | None | |
| DB Connectionaiskillstore/marketplace | 430 | — | ~3.5k | Automated safety check: Notes | None |
martin-ueding/geo-activity-playground
How to change the SQLAlchemy data model and generate the matching Alembic migration.
maksimzayats/specx
Add or repair Alembic migrations for specx SQLAlchemy services.
maksimzayats/specx
Add technical infrastructure adapters for specx core scopes.
aiskillstore/marketplace
SQLAlchemy and database patterns for Python. An agent skill from aiskillstore/marketplace.
aiskillstore/marketplace
A skill your agent uses when setting up database connections, especially for Neon PostgreSQL.
kurealnum/dotfiles
A skill your agent uses when generating or regenerating Drizzle migration files, changing database schema tables or columns, resolving migration sequence conflicts after rebase, reviewing migration…
kid-sid/claude-spellbook
A skill your agent uses when building or reviewing UI components for keyboard and screen reader compatibility, adding ARIA to custom widgets, auditing a page for WCAG AA conformance, or preparing…
kid-sid/claude-spellbook
A skill your agent uses when building, wiring, or debugging an Agentex agent — choosing agent type, configuring acp.py and manifest.yaml, using adk.messages or adk.state, or resolving…
kid-sid/claude-spellbook
A skill your agent uses when building production LLM applications — designing RAG pipelines, choosing vector databases, implementing agent orchestration, optimizing cost, or adding AI safety…
kid-sid/claude-spellbook
A skill your agent uses when building or refactoring Angular applications — choosing between signals, RxJS, and NgRx for state, configuring routing with guards and lazy loading, optimizing change…
kid-sid/claude-spellbook
A skill your agent uses when designing new REST endpoints, reviewing an existing API contract, adding pagination or filtering, planning a versioning strategy, or building a public or partner-facing…
kid-sid/claude-spellbook
A skill your agent uses when implementing login flows, issuing or validating JWTs, setting up OAuth2/OIDC with a provider, designing role-based or attribute-based access control, securing API…
Works with
Categories
A skill your agent uses when using async SQLAlchemy 2.0 — defining models, writing queries, managing async sessions, loading relationships without N+1, or setting up and debugging Alembic migrations. Sqlalchemy is an agent skill from kid-sid/claude-spellbook.0 — defining models, writing queries, managing async sessions, loading relationships without N+1, or setting up and debugging Alembic migrations.
Sqlalchemy fits situations like: using async SQLAlchemy 2.0 — defining models; writing queries; managing async sessions; loading relationships without N+1.
Run `npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a claude-code`. Or copy the skill folder (skills/sqlalchemy in kid-sid/claude-spellbook) into .claude/skills/sqlalchemy in your project. Claude Code loads it when a task matches its description.
Run `npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a codex`. Or copy the skill folder (skills/sqlalchemy in kid-sid/claude-spellbook) into .agents/skills/sqlalchemy in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kid-sid/claude-spellbook --skill sqlalchemy -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sqlalchemy, .gemini/skills/sqlalchemy, .github/skills/sqlalchemy and .opencode/skills/sqlalchemy in your project.
Going by SKILL.md and its folder, Sqlalchemy needs the command-line tools its instructions call (make). Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Sqlalchemy is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.5k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Sqlalchemy: Change Database Schema (martin-ueding/geo-activity-playground, 100 stars), Specx Sqlalchemy Migrations (maksimzayats/specx, 202 stars), Specx Add Infrastructure Adapter (maksimzayats/specx, 202 stars) and Python Database Patterns (aiskillstore/marketplace, 430 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
kid-sid (a GitHub user) maintains it in kid-sid/claude-spellbook, which has 189 GitHub stars. The repository holds 54 skills in this directory. The repository was last updated on August 5, 2026.
Source: kid-sid/claude-spellbook on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.