HybridModel¶
A Pydantic model with built-in Marshmallow support.
Class¶
HybridModel
¶
Bases: BaseModel
A Pydantic model that can also work as a Marshmallow schema.
This provides a single class that gives you both Pydantic model capabilities AND Marshmallow schema functionality.
Instance Caching
ma_load() / ma_dump() cache a default schema instance for
performance. Schemas with hooks (pre_load, post_load, @validates,
@validates_schema, pre_dump, post_dump) always get a fresh instance to prevent leaked
mutable state. The cache is protected by an RLock.
Example
class User(HybridModel): name: str email: EmailStr age: int = Field(ge=0)
Use as Pydantic model¶
user = User(name="Alice", email="alice@example.com", age=30)
Use for Marshmallow-style loading¶
user = User.ma_load({"name": "Alice", "email": "alice@example.com", "age": 30})
Get the Marshmallow schema¶
schema = User.marshmallow_schema()
marshmallow_schema
classmethod
¶
Get or create the Marshmallow schema for this model (thread-safe).
ma_load
classmethod
¶
Load data using the Marshmallow schema.
ma_loads
classmethod
¶
Load data from a JSON string using the Marshmallow schema.
ma_dumps
¶
Dump this instance to a JSON string using the Marshmallow schema.
Usage¶
Basic Usage¶
from pydantic_marshmallow import HybridModel
from pydantic import Field
class User(HybridModel):
name: str
email: str
age: int = Field(ge=0)
# Use as a Pydantic model
user = User(name="Alice", email="alice@example.com", age=30)
print(user.model_dump()) # Pydantic method
# Use Marshmallow methods
data = user.ma_dump() # Marshmallow serialization
json_str = user.ma_dumps() # Marshmallow JSON serialization
# Load via Marshmallow
user = User.ma_load({"name": "Bob", "email": "bob@example.com", "age": 25})
user = User.ma_loads('{"name": "Charlie", "email": "c@example.com", "age": 35}')
Getting the Schema Class¶
For ecosystem integration:
# Get the Marshmallow schema class
UserSchema = User.marshmallow_schema()
# Use with webargs
@use_args(UserSchema(), location="json")
def create_user(user):
pass
# Use with apispec
spec.components.schema("User", schema=UserSchema)
Validation¶
HybridModel uses Pydantic's strict behavior by default:
class StrictUser(HybridModel):
name: str
age: int
# Marshmallow load uses Pydantic validation
try:
user = StrictUser.ma_load({"name": "", "age": -5})
except ValidationError as e:
print(e.messages)
When to Use HybridModel¶
Use HybridModel when you need:
- Both Pydantic and Marshmallow APIs on the same class
- A drop-in replacement that works with existing Pydantic code
- Simple cases without custom schema configuration
Use PydanticSchema when you need:
- Custom hooks (
@pre_load,@post_load, etc.) - Custom validators on the schema
- Field filtering (
only,exclude,load_only,dump_only) - Full control over schema behavior
Performance¶
Instance Caching¶
HybridModel caches default schema instances for hookless schemas, avoiding
the overhead of creating a new schema object on every ma_load() / ma_dump() call.
- Hookless schemas: Cached and reused (thread-safe via
RLock) - Schemas with hooks: Fresh instance every call to prevent mutable state leaks
- Passing
**kwargsto anyma_load*/ma_dump*method always creates a fresh instance
Thread Safety¶
All ma_load(), ma_loads(), ma_dump(), and ma_dumps() methods are safe
to call from multiple threads concurrently.