Marshmallow 入门指南(Python 数据序列化与校验)

Marshmallow 是 Python 老牌序列化与校验库:Schema 定义、字段校验、错误处理、嵌套与数据转换。本文讲解 Marshmallow 的核心用法与 API 实战。

最佳实践
并发任务的多路径协同插画

直接回答:Marshmallow 负责在复杂 Python 对象与简单数据类型之间双向转换(序列化/反序列化),并在入口把关数据校验——构建 API、处理表单、清洗管道数据都离不开它。 Schema 声明式定义,一次编写两用(进出都管)。

快速上手

pip install marshmallow
from marshmallow import Schema, fields, validate

class UserSchema(Schema):
    name = fields.Str(required=True)
    email = fields.Email(required=True)
    age = fields.Int(validate=validate.Range(min=0, max=150))
    created_at = fields.DateTime(dump_only=True)   # 只输出,不接受输入

schema = UserSchema()

# 反序列化 + 校验(进来的数据)
user = schema.load({"name": "张三", "email": "zs@example.com", "age": 28})

# 序列化(出去的数据)
schema.dump(user)   # -> {"name": "张三", ...}

load 管入(校验)、dump 管出(序列化)——dump_only/load_only(如密码字段)精确控制方向。

自定义校验

from marshmallow import validates, ValidationError

class UserSchema(Schema):
    name = fields.Str(required=True)
    password = fields.Str(load_only=True, required=True)

    @validates("password")
    def check_password(self, value, **kwargs):
        if len(value) < 8:
            raise ValidationError("密码至少 8 位")

多字段联合校验用 @validates_schema(如"两次密码一致")。

错误处理

校验失败抛 ValidationError,错误按字段组织:

def validate_user(data):
    try:
        user = schema.load(data)
    except ValidationError as err:
        return {"errors": err.messages}, 400
    return user, 200
# {"errors": {"email": ["Not a valid email address."]}}

API 视图里把这个结构直接返回给前端——表单逐字段标红的数据就是它。

嵌套与转换

class AuthorSchema(Schema):
    name = fields.Str()

class BookSchema(Schema):
    title = fields.Str()
    author = fields.Nested(AuthorSchema)          # 嵌套对象
    tags = fields.List(fields.Str())               # 列表
    price = fields.Decimal(as_string=True)         # Decimal 以字符串输出

数据整形三板斧:Nested 嵌套、Method 字段自定义计算、pre_load/post_dump 钩子在加载前后做转换(如兼容老格式字段名)。

实战中的位置

Marshmallow 不绑定任何框架:Flask-Marshmallow 提供框架集成,模型 Schema 自动生成还需 marshmallow-sqlalchemy;独立数据管道里它做 ETL 入口的清洗关卡;和 SQLAlchemy 组合(marshmallow-sqlalchemy)可以自动从表结构生成 Schema。

常见问题(FAQ)

Q:Marshmallow 和 Pydantic 怎么选?
A:Pydantic v2 使用 Rust 校验内核,性能需按数据与规则测量、类型注解风格更现代,FastAPI 生态默认它;Marshmallow 的 load/dump 双向语义与字段方向控制在"进出不对称"的场景更清晰,Flask 生态集成深。新项目无历史包袱偏 Pydantic,存量 Flask 继续 Marshmallow。

Q:性能敏感场景要注意什么?
A:序列化上万对象的循环里,先测量实际 Schema、钩子和数据形状的成本。可减少不必要的 Nested 层级,再用相同语义比较其他库,不预设性能排名。

Q:未知字段怎么处理?
A:Meta 里 公开资料未说明 = RAISE/EXCLUDE/INCLUDE 三选一。默认 RAISE 可暴露拼写或契约错误;EXCLUDE 会忽略未知输入,INCLUDE 保留未校验字段,应按安全与兼容要求显式选择。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台