litestar-org/litestar-skills/advanced-alchemy

Claude Code and agent skill by litestar-org/litestar-skills

Trust tier 2
  • community
  • ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Auto-activate for advanced_alchemy, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type, service_class, filters, or storage. Not for raw SQLAlchemy — use sqlspec.

Install

npx vskill@latest install litestar-org/litestar-skills/advanced-alchemy

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

Advanced Alchemy

Code Style Rules

  • Use Mapped[...] for columns and T | None for optional fields.
  • Keep business transformations in service lifecycle hooks.
  • Prefer the inner Repo service pattern and advanced_alchemy.* imports.
  • Use from __future__ import annotations when it matches the project; 1.12

supports it in model modules.

Match-Your-Framework — read first

advanced-alchemy ships first-party extensions for five web frameworks. If your project uses one of these, jump directly to the matching integration guide and skip the others:

  • Litestar — SQLAlchemyPlugin with full DI, session store, CLI. The rest of this SKILL.md covers Litestar by default; also see `references/litestar_plugin.md`.
  • FastAPI → `references/fastapi-integration.md` — AdvancedAlchemy(config=..., app=app), Depends(alchemy.provide_session()) DI, provide_service()/provide_filters(), Alembic CLI via assign_cli_group.
  • Flask → `references/flask-integration.md` — AdvancedAlchemy(config=..., app=app) or init_app() factory, pull-based alchemy.get_sync_session(), async-via-portal.
  • Sanic → `references/sanic-integration.md` — AdvancedAlchemy(sqlalchemy_config=..., sanic_app=app) (note: sqlalchemy_config= kwarg, not config=), sanic-ext DI, request.ctx sessions.
  • Starlette → `references/starlette-integration.md` — AdvancedAlchemy(config=..., app=app), request.state session access, lifespan wrapping.

Transaction configuration is framework-specific. Litestar uses before_send_handler; FastAPI, Flask, Starlette, and Sanic use commit_mode="manual", "autocommit", or "autocommit_include_redirect". Read the matching framework guide, then `references/commit-modes.md` and `references/multi-database.md`.

The rest of this SKILL.md covers framework-agnostic topics: base classes, repositories, services, filters, custom types, caching, replicas, operations, and Alembic migrations.

Overview

Advanced Alchemy is NOT a raw ORM — it is a service/repository layer built on top of SQLAlchemy 2.0+ with opinionated base classes, audit mixins, and deep framework integrations (Litestar, FastAPI, Flask, Starlette, Sanic). It provides:

  • Base models with automatic id, created_at, updated_at fields
  • Repository pattern for type-safe async CRUD
  • Service layer with lifecycle hooks (to_model_on_create, to_model_on_update, to_model_on_upsert, to_model_on_delete)
  • Framework plugins for automatic session/transaction management
  • Custom types: EncryptedString, EncryptedText, PasswordHash, FileObject, StoredObject, DateTimeUTC, GUID, Bool, JsonB, Vector, TOTPSecret, OneTimeCode
  • Alembic integration for migrations via CLI

Quick Reference

Base Classes
Base ClassPK TypeAudit ColumnsWhen to Use
UUIDAuditBaseUUID v4created_at, updated_atDefault choice for most models
UUIDBaseUUID v4NoneLookup tables, tags, no audit needed
UUIDv7AuditBase / UUIDv7BaseUUID v7created_at, updated_at / NoneTime-ordered IDs when uuid-utils is installed or Python supplies UUIDv7
UUIDv6AuditBase / UUIDv6BaseUUID v6created_at, updated_at / NoneTime-ordered UUIDv6 IDs
BigIntAuditBase / BigIntBaseBigInt auto-incrementcreated_at, updated_at / NoneLegacy systems, integer PKs
NanoIDAuditBase / NanoIDBaseNanoID stringcreated_at, updated_at / NoneURL-friendly short IDs
IdentityAuditBase / IdentityBasedatabase identitycreated_at, updated_at / NoneNative IDENTITY columns
DefaultBaseNone (define yourself)NoneCustom or composite primary keys with AA table naming
SQLQueryNoneNoneCustom mapped read-only SQL query projections
Repository Pattern
RepositoryPurpose
SQLAlchemyAsyncRepository[Model] / SQLAlchemySyncRepository[Model]Standard async/sync CRUD
SQLAlchemyAsyncSlugRepository[Model] / SQLAlchemySyncSlugRepository[Model]CRUD + slug generation helpers
SQLAlchemyAsyncQueryRepository / SQLAlchemySyncQueryRepositoryComplex read-only queries (no model_type)
Service Layer
ServicePurpose
SQLAlchemyAsyncRepositoryService[Model] / SQLAlchemySyncRepositoryService[Model]Full CRUD with lifecycle hooks
SQLAlchemyAsyncRepositoryReadService[Model] / SQLAlchemySyncRepositoryReadService[Model]Read-only (get_many, get, count, exists)
SQLAlchemyAsyncQueryService / SQLAlchemySyncQueryServiceService wrapper around arbitrary SQL queries

Key lifecycle hooks: to_model_on_create, to_model_on_update, to_model_on_upsert, to_model_on_delete.

Custom Types

TypePurposeNotes
FileObject / StoredObjectObject storage with lifecycle hooksTracks file state across session; auto-deletes on row delete via StoredObject tracker; use FileObjectList for multi-file JSON arrays
PasswordHashHashed password storageSupports Argon2, Passlib, and Pwdlib backends; returns HashedPassword with .verify() and .verify_and_update()
EncryptedString / EncryptedTextTransparent encryption at restSupports FernetBackend (client-side) and PGCryptoBackend (server-side); pass a stable key explicitly
GUIDCross-dialect UUID columnNative UUID on PostgreSQL/DuckDB/CockroachDB, BINARY(16) or CHAR(32) fallback elsewhere; pair with UUIDv7AuditBase / UUIDv6AuditBase for time-sortable UUIDs
DateTimeUTCTimezone-aware UTC datetimeStores as UTC; normalizes or raises on naive datetimes
BoolDialect-aware booleanUses Oracle 23ai native BOOLEAN when SQLAlchemy exposes it; falls back to stock SQLAlchemy Boolean
JsonBDialect-aware JSON / JSONBUses JSONB on PostgreSQL/CockroachDB, JSON on other backends, BLOB with OSON on Oracle
VectorDialect-aware vector storage and distance operatorsOracle 23ai VECTOR, PostgreSQL/CockroachDB pgvector, JSON fallback without distance operators
TOTPSecret / OneTimeCodeMFA and single-use code storageTOTPSecret encrypts shared secrets and returns TOTPProvider; OneTimeCode hashes codes with TTL/attempt tracking and returns HashedOneTimeCode

Repository Service Layer

SQLAlchemyAsyncRepositoryService is the primary service base class. Key behaviors:

  • Dict-to-model conversion: pass raw dict to create(), update(), upsert() — the service converts via to_model_on_create / to_model_on_update lifecycle hooks before persistence
  • Bulk operations: create_many(data), update_many(data), upsert_many(data, match_fields=..., no_merge=False, chunk_size=None), delete_many(item_ids) — batched in a single transaction; upsert_many() dispatches to native dialect primitives (ON CONFLICT, ON DUPLICATE KEY UPDATE, MERGE, Spanner INSERT OR UPDATE) via resolve_upsert_strategy() when uniqueness is provable, and delete_many() accepts raw primary keys, composite-key tuples/dicts, model instances, or mixed lists
  • Lifecycle hooks: to_model_on_create, to_model_on_update, to_model_on_upsert — override to transform input data, hash passwords, normalize strings, etc.

Mixins

MixinFields AddedWhen to Use
AuditColumnscreated_at, updated_atAdd timestamps to a model with a custom primary key
SlugKeyunique slug columnPair with a slug repository; the mixin does not generate values
UniqueMixinas_unique_async() / as_unique_sync()Session-cached select-or-create after defining unique_hash() and unique_filter()
SentinelMixinhidden sa_orm_sentinel columnDeterministic ordering for SQLAlchemy bulk inserts; not optimistic locking

Litestar Integration

Use SQLAlchemyPlugin (composite of SQLAlchemyInitPlugin + SQLAlchemySerializationPlugin) for full integration:

  • `SQLAlchemyPlugin`: registers engine/session providers, a Litestar

before_send hook, and ORM type encoders in one call

  • `SQLAlchemyDTO`: generates Litestar DTOs directly from ORM models with include/exclude field control
  • Type encoders: automatic serialization of datetime, UUID, Decimal, Enum, and custom column types
  • Exception handling: set_default_exception_handler=True (the default)

registers RepositoryError: exception_to_http_response on the app — unless Litestar(exception_handlers={...}) contains any integer status-code key (500, 404, etc.), in which case SQLAlchemyInitPlugin skips default registration and you must register RepositoryError: exception_to_http_response explicitly

<workflow>

Workflow

Step 1: Define the Model

Choose the appropriate base class from the quick reference table. Use UUIDAuditBase unless you have a specific reason not to. Define columns with Mapped[] typing.

Step 2: Create the Repository

Create a repository class with model_type set to your model. Use SQLAlchemyAsyncRepository for standard CRUD, SQLAlchemyAsyncSlugRepository if the model uses SlugKey.

Step 3: Build the Service

Create a service class with an inner Repo class. Set match_fields for upsert logic. Add lifecycle hooks (to_model_on_create, to_model_on_update) for business logic transformations.

Step 4: Wire into Framework

Use the framework plugin (Litestar, FastAPI, Flask, Sanic) to inject sessions and register the service as a dependency.

Step 5: Generate Migration

With Litestar, run litestar database make-migrations -m "description" and then litestar database upgrade. With the standalone CLI, put the required config option before the command: alchemy --config path.to.config make-migrations -m "description".

</workflow>

<guardrails>

Guardrails

  • Always use the service layer for business logic — never put validation, hashing, or transformation logic directly in route handlers or repositories
  • Repositories are for data access only — no business rules, no side effects beyond database operations
  • Never bypass the service layer to call repository methods directly from handlers
  • Always set `match_fields` on services that use upsert() to avoid duplicate-key errors
  • Use `schema_dump()` / `schema_dump_config` for explicit dump behavior — services already convert Pydantic/msgspec/attrs/dataclass inputs during model conversion
  • Prefer `UUIDAuditBase` as default base class — only deviate when you have a concrete reason
  • Use `advanced_alchemy.*` imports — the old litestar.plugins.sqlalchemy paths are deprecated
  • Pass stable keys to `EncryptedString` and `EncryptedText`. Omitting

key= emits a 1.11 deprecation warning and produces data that cannot survive a process restart.

  • Use `get_many()` and `get_many_and_count()`. list() and

list_and_count() are deprecated until 2.0.

  • Explicitly register `RepositoryError: exception_to_http_response` when using integer status-code `exception_handlers` in Litestar. SQLAlchemyInitPlugin skips its default RepositoryError handler whenever any int key (500, 404, etc.) is present in Litestar(exception_handlers={...}).

</guardrails>

<validation>

Validation Checkpoint

Before delivering code, verify:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
16
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Extension points

  • hookPre/post lifecycle hooks

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/litestar-org/litestar-skills/advanced-alchemy/badge)](https://verified-skill.com/skills/litestar-org/litestar-skills/advanced-alchemy)

Something wrong with this skill or its page? Tell us.