marshmallow-sqlalchemy: deriving marshmallow schemas from SQLAlchemy models
SQLAlchemy integration with marshmallow
At a glance
- What is it?
- marshmallow-sqlalchemy is the bridge between two libraries that each want to own the same model: SQLAlchemy describes the database shape, marshmallow handles serialization, and this library generates one from the other. You can declare fields by hand with auto_field or let the library derive them from the model with SQLAlchemyAutoSchema.
- Who is it for?
- marshmallow-sqlalchemy fits a Python API project that already uses SQLAlchemy for its models and marshmallow for its payloads, and that does not want to write a field list twice. It does not fit a team that wants a single library for both jobs, and it does not fit a codebase on marshmallow 3, since the current release requires marshmallow 4.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two libraries that each want to describe the same object
marshmallow-sqlalchemy is the integration between the SQLAlchemy ORM and the marshmallow serialization library, and the project describes it plainly as a SQLAlchemy integration with the marshmallow (de)serialization library. The problem it solves is duplication. SQLAlchemy models describe columns, types, keys and relationships, and marshmallow schemas describe fields for input and output. Write both by hand and they drift, and the drift shows up as a serialization layer that quietly disagrees with the database. This library makes the schema derive from the model, or gives you per-field helpers so the schema is short enough to read and check by hand. The model stays the single source of truth, which is the point of the whole exercise.
Declaring the models, and the schema that goes with them
The README's walkthrough declares an Author and a Book model, then writes the matching schemas by hand using the auto_field helper.
from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field
class AuthorSchema(SQLAlchemySchema):
class Meta:
model = Author
load_instance = True # Optional: deserialize to model instances
id = auto_field()
name = auto_field()
books = auto_field()
class BookSchema(SQLAlchemySchema):
class Meta:
model = Book
load_instance = True
id = auto_field()
title = auto_field()
author_id = auto_field()The load_instance flag in the Meta class is the one that changes the behaviour most, because it makes the schema deserialize into model instances rather than plain dictionaries. The auto_field calls then do the per-column work, and the relationship field on the author schema is what pulls in the books.
SQLAlchemyAutoSchema, and the two options that control derivation
You can also let the library generate the fields for a model's columns, using SQLAlchemyAutoSchema, and the README says the resulting classes are equivalent to the hand-written ones above.
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema
class AuthorSchema(SQLAlchemyAutoSchema):
class Meta:
model = Author
include_relationships = True
load_instance = True
class BookSchema(SQLAlchemyAutoSchema):
class Meta:
model = Book
include_fk = True
load_instance = TrueThe two options decide how much the schema follows the model. include_relationships brings in the related objects rather than just their keys, which is convenient for nested output and expensive for large graphs. include_fk pulls in the foreign key columns, which is what you want when the client needs to reference the parent but should not receive the nested object. Neither is set by default, which is a sensible default given that one of them is usually wrong for a given API.
Declare the models before the schemas, or the mappers run too soon
There is one ordering requirement that the README calls out explicitly. Make sure to declare Models before instantiating Schemas, otherwise sqlalchemy.orm.configure_mappers() will run too soon and fail. The reason is that the schema class body reads the model's mapper metadata, and the mapper configuration is what resolves relationships and column types. If the schema is imported before the models are defined, the mapper configuration runs against a half-defined model graph and raises. It is a simple rule, but it is the kind of thing that produces a confusing error the first time, because the traceback points into the ORM rather than into your import order. The same ordering discipline applies to the auto-generated schemas, since they inspect the model at class definition time.
Dumping and loading, with the session passed in on load
The (de)serialization section shows the round trip.
author = Author(name="Chuck Paluhniuk")
author_schema = AuthorSchema()
book = Book(title="Fight Club", author=author)
with Session() as session:
session.add(author)
session.add(book)
session.commit()
dump_data = author_schema.dump(author)
print(dump_data)
# {'id': 1, 'name': 'Chuck Paluhniuk', 'books': [1]}
with Session() as session:
load_data = author_schema.load(dump_data, session=session)
print(load_data)
# <Author(name='Chuck Paluhniuk')>Two details are worth noting. The dumped books value is a list of identifiers rather than nested author objects, which is the include_relationships default in action, and the load call passes the session explicitly, so the deserialized Author is attached to it and can be committed. That session argument is the part people miss, since load returns a model instance and someone will assume it was persisted.
Version floors, and a project moving to uv and flit
The packaging details in the project file tell you how actively it is maintained. The version is 1.6.0, the licence is MIT, and the dependencies are marshmallow 4.0.0 or newer and SQLAlchemy 1.4.40 or newer but below 3.0. The Python requirement is 3.10 or newer, with classifiers running from 3.10 through 3.14, and the maintainer is Steven Loria. The build backend is flit_core below 5, and the development tooling has moved to uv, with a uv.lock file at the root, a default dev group, and an exclude-newer setting of one week, which is a reproducible-build measure that pins dependency resolution to a week-old snapshot. The documentation groups are declared as dependency groups rather than extras, with docs, tests and lint groups, and tox with tox-uv for running the matrix. The tooling around the project is ruff for linting and formatting with a select of all checks minus an explicit ignore list, pre-commit for hooks, and renovate for dependency updates.
Editorial conclusion
marshmallow-sqlalchemy fits a Python API project that already uses SQLAlchemy for its models and marshmallow for its payloads, and that does not want to write a field list twice. It does not fit a team that wants a single library for both jobs, and it does not fit a codebase on marshmallow 3, since the current release requires marshmallow 4. Verify first that your SQLAlchemy version falls inside the supported range, since the dependency floor is 1.4.40 and the ceiling is below 3.0, and declare your models before instantiating your schemas, because the mapper configuration runs at import time and will fail if the order is wrong.
Frequently asked questions
What does marshmallow-sqlalchemy do?
It integrates the SQLAlchemy ORM with the marshmallow serialization library so you do not have to describe the same fields twice. You can generate fields automatically from a model's columns with SQLAlchemyAutoSchema, or declare them yourself with the auto_field helper on a SQLAlchemySchema subclass.
Why do I get an error if I define a schema before my models?
The schema reads the model's mapper metadata, so sqlalchemy.orm.configure_mappers() runs too soon and fails. The README instructs you to declare the Models before instantiating the Schemas.
What do include_relationships and include_fk do?
include_relationships brings related objects into the schema rather than just their keys, and include_fk includes the foreign key columns. The auto-generated equivalent of the hand-written schemas in the README uses include_relationships for the author and include_fk for the book.
Which versions of SQLAlchemy and marshmallow are supported?
The package requires marshmallow 4.0.0 or newer and SQLAlchemy 1.4.40 or newer but below 3.0, and Python 3.10 or newer. The current version is 1.6.0 and the licence is MIT.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/marshmallow-code-marshmallow-sqlalchemy)Was this useful?