Automatic Pydantic Schemas for SQLAlchemy models
Project description
schemap
Automatic Pydantic v2 schemas from SQLAlchemy 2.0 ORM models. Define your model once. The schemas come automatically.
pip install schemap
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.
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:
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]
@auto_schema — decorate any existing model without changing its base class:
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]
Both 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 includes two 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.
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.
Requirements
Python 3.12 or later, SQLAlchemy 2.0.49 or later, Pydantic 2.13.4 or later.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file schemap-0.5.2.tar.gz.
File metadata
- Download URL: schemap-0.5.2.tar.gz
- Upload date:
- Size: 17.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
089d9ba97a4b5931e2ae91a478c2e3eb45bb129c10f0bebf780a727b59302626
|
|
| MD5 |
eb9d7cf4a239cdfcbe69e34dfdcd18c5
|
|
| BLAKE2b-256 |
98981076416cea92634939d70ff2f59b3a2912eafe17c2f3477c1d5e4874a229
|
File details
Details for the file schemap-0.5.2-py3-none-any.whl.
File metadata
- Download URL: schemap-0.5.2-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
567972ecc4bcef9fe68869cfeb435c90de370bc856ef85905ba95cbf1de25016
|
|
| MD5 |
ba936ebb9cab6d570b6e87a0e9b63dfe
|
|
| BLAKE2b-256 |
95f6b11788662484b5e328b61181d22428557c9be073e23c4b4da701637d0a95
|