Skip to main content

schemap

Automatic Pydantic v2 schemas from SQLAlchemy 2.0 ORM models. Define your model once. The schemas come automatically.

Python License Documentation DeepWiki PyPI

pip install schemap

Requires Python 3.12 or later, SQLAlchemy 2.0.49 or later, Pydantic 2.13.4 or later.

Why Schemap

Writing Pydantic schemas for SQLAlchemy models is repetitive work. You maintain four schemas per model: full, create, update, and public. Each schema must stay synchronized with column changes, nullability updates, and new constraints. Schemap eliminates this duplication by generating all four schemas directly from your model definition.

The library reads your SQLAlchemy columns and translates them into Pydantic fields. A primary key becomes excluded from CreateSchema. A server default becomes excluded from write operations. A nullable column becomes an Optional field. You focus on your model. Schemap handles the validation layer.

What makes schemap unique

1. Four-variant generation as a first-class concept. No other library auto-generates full, create, update, and public schemas with intelligent exclusion rules out of the box. Primary keys are excluded from create. All fields become optional in update. Private fields are filtered from public. These rules are not something you configure; they are built in.

2. Strict separation between ORM and validation. SQLAlchemy stays pure SQLAlchemy. Pydantic stays Pydantic. Schemap never fuses them into a single class. Your ORM models remain unaware of your API layer. You can swap Pydantic versions, switch validation libraries, or use your models outside of FastAPI without touching a single column definition.

3. Three API modes. Use AutoBase inheritance for new projects. Use SchemaMixin to mix into your own declarative base. Use @auto_schema to decorate existing models without changing their base class. All three produce identical results.

4. Per-model customization via SchemaConfig. Attach a SchemaConfig to any model to override field types, exclude fields from specific variants, force required or optional status, and add custom validators. The model itself stays clean; the configuration lives in one place.

Quick Start

Schemap gives you three ways to attach schemas to your models. All three produce identical schemas.

AutoBase: inherit from the ready-made declarative base. Best for new projects where you have no existing base:

from schemap import AutoBase
from sqlalchemy.orm import Mapped, mapped_column

class User(AutoBase):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]
    email: Mapped[str]

SchemaMixin: mix into your own declarative base. Best when you already have a custom DeclarativeBase and want to keep it:

from schemap import SchemaMixin
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

class Base(SchemaMixin, DeclarativeBase):
    pass

class User(Base):
    __tablename__ = "users"
    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]
    email: Mapped[str]

@auto_schema: decorate any existing model without changing its base class. Best when you cannot change the model's base (third-party models, large codebases):

from schemap import auto_schema
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

class Base(DeclarativeBase):
    pass

@auto_schema
class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]
    email: Mapped[str]

All three approaches give you the same four schemas and conversion methods:

User.Schema         # all columns
User.CreateSchema   # excludes primary keys and server defaults
User.UpdateSchema   # all fields optional for partial updates
User.PublicSchema   # excludes fields starting with __

# Convert between ORM and Pydantic
data = User.CreateSchema(name="Alice", email="alice@example.com")
user = User.from_schema(data)
schema = user.to_schema()

The decorator also accepts a config argument:

@auto_schema(config=SchemaConfig(exclude_public=["email"]))
class User(Base):
    ...

SchemaConfig

Customize generated schemas per model using the __schema_config__ attribute.

from schemap import AutoBase, SchemaConfig
from sqlalchemy.orm import Mapped, mapped_column

class User(AutoBase):
    __tablename__ = "users"
    __schema_config__ = SchemaConfig(
        exclude_public=["email"],
        exclude_create=["internal_id"],
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str]
    email: Mapped[str]
    internal_id: Mapped[int]

The SchemaConfig class supports several exclusion options. exclude_always removes a field from all schemas. exclude_create, exclude_update, and exclude_public target specific schema variants. field_overrides lets you change a field's Python type. required_always and optional_always override nullability rules.

Built-in Mixins

Schemap ships with nine reusable mixins for common model patterns.

TimestampMixin adds created_at and updated_at columns. The timestamps set automatically on insert and update.

SoftDeleteMixin adds a deleted_at column, a soft_delete() method, and an active() classmethod filter for excluding deleted records.

CreatedByMixin and UpdatedByMixin add audit trail fields with foreign keys and relationships to a users table. Override user_table on subclasses to target a different table.

StatusMixin adds a status column with activate() and deactivate() methods.

ArchivableMixin adds an archived_at timestamp with archive() and restore() methods.

VersionMixin adds a version int column with increment_version() for optimistic locking.

UUIDPrimaryKeyMixin and IntPrimaryKeyMixin provide standard primary key columns.

from schemap import AutoBase, TimestampMixin, SoftDeleteMixin

class User(AutoBase, TimestampMixin):
    __tablename__ = "users"
    name: Mapped[str]

class Post(AutoBase, SoftDeleteMixin):
    __tablename__ = "posts"
    title: Mapped[str]

Custom Validators

Attach validation functions to any field using extra_validators in SchemaConfig. The validator receives the field value and must return it or raise ValueError.

from schemap import AutoBase, SchemaConfig

def validate_positive(value: int) -> int:
    if value <= 0:
        raise ValueError("Value must be positive")
    return value

class Product(AutoBase):
    __tablename__ = "products"
    __schema_config__ = SchemaConfig(extra_validators={"price": validate_positive})
    
    price: Mapped[float]

Standalone Usage

Use build_schema directly when you need a schema without modifying the model class.

from schemap import build_schema
from schemap.config import SchemaConfig

UserSchema = build_schema(User, schema_type="create", config=SchemaConfig(exclude_create=["internal_id"]))

Decorator API

Use @auto_schema to attach schemas to any SQLAlchemy model without inheritance.

from schemap import auto_schema, SchemaConfig

# Bare decorator, all defaults
@auto_schema
class User(Base):
    __tablename__ = "users"
    ...

# With config
@auto_schema(config=SchemaConfig(exclude_public=["email"]))
class User(Base):
    ...

The decorator runs after the class body and attaches .Schema, .CreateSchema, .UpdateSchema, .PublicSchema, .from_schema(), and .to_schema() directly to your class. Your model's inheritance chain stays unchanged.

License

MIT

Metadata

Release files for schemap 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for schemap 0.7.0
File Size Uploaded Provenance Actions
schemap-0.7.0.tar.gz 27.2 kB With provenance Details for schemap-0.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for schemap 0.7.0
File Interpreter ABI Platform Actions
schemap-0.7.0-py3-none-any.whl Python 3 none any Details for schemap-0.7.0-py3-none-any.whl

Total release size: 47.7 kB

Release files / schemap-0.7.0.tar.gz

Download URL schemap-0.7.0.tar.gz
Size 27.2 kB
Tags Source
SHA-256 checksum
How to use checksums
83373bcffb72a824163518d04a1f98ea65cbe368c35a2085065d3ceba015b784
BLAKE2b-256 checksum
How to use checksums
7017a4a4477ab06b27aaf373920e0f44e42de7582efe9f0a1b76ad9908210552
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / schemap-0.7.0-py3-none-any.whl

Download URL schemap-0.7.0-py3-none-any.whl
Size 20.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d05fd16463d135fec6e2ec71d708e9c5e2981e7168eca56a1c8e8ea584614d5
BLAKE2b-256 checksum
How to use checksums
9f9547147029a0987ceecd5deac710dbd13b2d683d484a6ccd3bb87659915820
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Security for schemap 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for schemap-0.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page