SQLAlchemy Serializer
SQLAlchemy Serializer (sqlalchemy-serializer) is a mixin for SQLAlchemy models that simplifies their serialization into dictionaries or JSON, often used in API contexts. It handles relationships, allows field exclusion/inclusion, and supports nested serialization. The current version is 1.6.2, and it typically sees regular maintenance releases.
Common errors
-
AttributeError: 'User' object has no attribute 'to_dict'
cause Your SQLAlchemy model class does not inherit from `SerializerMixin`.fixEnsure your model class inherits from `SerializerMixin`: `class MyModel(Base, SerializerMixin):` -
ModuleNotFoundError: No module named 'sqlalchemy_serializer'
cause The `sqlalchemy-serializer` library is not installed, or you have a typo in the import statement.fixInstall the library: `pip install sqlalchemy-serializer`. Then ensure the import is correct: `from sqlalchemy_serializer import SerializerMixin`. -
RecursionError: maximum recursion depth exceeded while calling a Python object
cause You are trying to serialize models with circular relationships (e.g., parent-child where child also references parent) without limiting the nesting depth.fixWhen calling `to_dict()`, specify `max_nesting` (e.g., `obj.to_dict(max_nesting=1)`), or use `exclude` to prevent the problematic relationship field from being serialized. You can also define `_serializer_exclude_fields` on your model for permanent exclusion. -
TypeError: Object of type <class 'uuid.UUID'> is not JSON serializable
cause You have a field in your model with a custom Python type (like `UUID`, `datetime` in some contexts, custom enums, etc.) that the default JSON serializer doesn't know how to convert.fixFor `datetime` objects, `sqlalchemy-serializer` usually handles them. For other custom types, you might need to convert them to a serializable format (like `str`) before calling `to_dict()`, or extend `serializer_args` on the `SerializerMixin` to provide custom encoders if you're directly converting to JSON using `json.dumps` after `to_dict()`.
Warnings
- gotcha When serializing models with circular relationships (e.g., a User has Posts, and a Post references back to a User), `to_dict()` can lead to `RecursionError`. The serializer attempts to infinitely nest related objects.
- gotcha The `_serializer_exclude_fields` class variable on a model permanently excludes fields from serialization unless explicitly overridden. If you define this on your model, those fields will not appear by default in `to_dict()` output.
- breaking `sqlalchemy-serializer` requires `marshmallow>=3.0.0`. Using older versions of Marshmallow (e.g., 2.x) will lead to import errors or unexpected behavior due to API changes in Marshmallow.
- gotcha While `sqlalchemy-serializer` aims to be compatible with SQLAlchemy 2.0, users migrating to SQLAlchemy 2.0 might still encounter issues if their model declarations or session management patterns are not fully updated to SQLAlchemy 2.0's idiomatic style (e.g., using `Mapped` types or `session.scalars()`).
Install
-
pip install sqlalchemy-serializer
Imports
- SerializerMixin
from sqlalchemy_serializer import SerializerMixin
Quickstart
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy_serializer import SerializerMixin
Base = declarative_base()
class User(Base, SerializerMixin):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
email = Column(String)
def __repr__(self):
return f"<User(id={self.id}, name='{self.name}')>"
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
user = User(name='Alice', email='alice@example.com')
session.add(user)
session.commit()
# Serialize to dictionary
user_dict = user.to_dict()
print("Serialized User:", user_dict)
# Serialize with specific fields
user_name_only = user.to_dict(only=('name',))
print("User name only:", user_name_only)
session.close()