SQLAlchemy integration with the marshmallow (de)serialization library
—
Schema generation capabilities in marshmallow-sqlalchemy, providing two approaches for creating marshmallow schemas from SQLAlchemy models: automatic generation and manual field declaration.
Base schema class for manual field declaration using auto_field() to specify which model columns to include and how to configure them.
class SQLAlchemySchema(LoadInstanceMixin.Schema[_ModelType], Schema):
"""Schema for SQLAlchemy model or table with manual field declaration.
Use with auto_field() to generate fields from columns.
"""
OPTIONS_CLASS = SQLAlchemySchemaOptsfrom marshmallow_sqlalchemy import SQLAlchemySchema, auto_field
from mymodels import User
class UserSchema(SQLAlchemySchema):
class Meta:
model = User
load_instance = True
sqla_session = session
id = auto_field(dump_only=True)
username = auto_field()
email = auto_field()
created_at = auto_field(dump_only=True)
# Custom field with overrides
password_hash = auto_field(column_name="password", load_only=True)Schema that automatically generates fields from all columns in a SQLAlchemy model or table, with options to control field inclusion.
class SQLAlchemyAutoSchema(SQLAlchemySchema[_ModelType]):
"""Schema that automatically generates fields from model columns.
Generates fields for all columns unless explicitly excluded.
"""
OPTIONS_CLASS = SQLAlchemyAutoSchemaOptsfrom marshmallow_sqlalchemy import SQLAlchemyAutoSchema
from mymodels import User, Post
class UserAutoSchema(SQLAlchemyAutoSchema):
class Meta:
model = User
load_instance = True
include_relationships = True
include_fk = False
exclude = ["password_hash"]
# Can still override specific fields
created_at = auto_field(dump_only=True)
class PostAutoSchema(SQLAlchemyAutoSchema):
class Meta:
table = Post.__table__ # Can use table instead of model
fields = ["id", "title", "content"] # Only include these fieldsFunction to mark a field for automatic generation from a model or table column, with support for field customization.
def auto_field(
column_name: str | None = None,
*,
model: type[DeclarativeMeta] | None = None,
table: sa.Table | None = None,
**kwargs
) -> SQLAlchemyAutoField:
"""Mark a field to autogenerate from a model or table.
Parameters:
- column_name: Name of column to generate field from. If None, matches field name
- model: Model to generate field from. If None, uses model from class Meta
- table: Table to generate field from. If None, uses table from class Meta
- **kwargs: Field argument overrides (dump_only, load_only, validate, etc.)
Returns:
SQLAlchemyAutoField instance for metaclass processing
"""class UserSchema(SQLAlchemySchema):
class Meta:
model = User
# Basic auto field - maps to column with same name
username = auto_field()
# Map to different column name
user_email = auto_field(column_name="email")
# Add field-specific options
created_at = auto_field(dump_only=True)
password = auto_field(load_only=True, validate=validate.Length(min=8))
# Use different model
profile_data = auto_field(column_name="data", model=UserProfile)Configuration classes that control schema behavior and field generation.
class SQLAlchemySchemaOpts(LoadInstanceMixin.Opts, SchemaOpts):
"""Options class for SQLAlchemySchema.
Attributes:
- model: SQLAlchemy model to generate schema from (mutually exclusive with table)
- table: SQLAlchemy table to generate schema from (mutually exclusive with model)
- load_instance: Whether to load model instances (default: False)
- sqla_session: SQLAlchemy session for deserialization
- transient: Whether to load instances in transient state (default: False)
- model_converter: ModelConverter class to use (default: ModelConverter)
"""
model: type[DeclarativeMeta] | None
table: sa.Table | None
load_instance: bool
sqla_session: Session | None
transient: bool
model_converter: type[ModelConverter]class SQLAlchemyAutoSchemaOpts(SQLAlchemySchemaOpts):
"""Options class for SQLAlchemyAutoSchema.
Additional attributes:
- include_fk: Whether to include foreign key fields (default: False)
- include_relationships: Whether to include relationships (default: False)
"""
include_fk: bool
include_relationships: boolclass UserSchema(SQLAlchemyAutoSchema):
class Meta:
# Model specification (choose one)
model = User # Use SQLAlchemy model
# OR
table = User.__table__ # Use table directly
# Instance loading
load_instance = True # Load as model instances
sqla_session = session # Session for loading
transient = False # Load persistent instances
# Field inclusion/exclusion
include_fk = True # Include foreign key fields
include_relationships = True # Include relationship fields
fields = ["id", "name"] # Only include these fields
exclude = ["password"] # Exclude these fields
# Custom converter
model_converter = CustomModelConverterWhen load_instance=True, schemas can deserialize data directly into SQLAlchemy model instances.
# Configure schema for instance loading
class UserSchema(SQLAlchemyAutoSchema):
class Meta:
model = User
load_instance = True
schema = UserSchema()
# Load as dictionary (default)
user_dict = schema.load({"name": "John", "email": "john@example.com"})
# Load as model instance
user_instance = schema.load(
{"name": "John", "email": "john@example.com"},
session=session
)
# Update existing instance
existing_user = session.get(User, 1)
updated_user = schema.load(
{"name": "Johnny"},
session=session,
instance=existing_user
)
# Load transient instance (not attached to session)
transient_user = schema.load(
{"name": "Jane"},
session=session,
transient=True
)Install with Tessl CLI
npx tessl i tessl/pypi-marshmallow-sqlalchemy