Marshmallow简介
Marshmallow是一个强大的Python库,用于简化复杂数据类型与Python原生数据类型之间的转换过程。它提供了一种简单、灵活的方式来:
序列化
将复杂数据类型(如ORM对象)转换为Python原生数据类型,以便转换为JSON等格式
反序列化
将Python原生数据类型(如来自JSON请求的数据)转换为复杂数据类型
数据验证
在反序列化过程中验证输入数据是否符合预期格式和约束
为什么选择Marshmallow? Marshmallow特别适合在Web API开发中使用,能够简化请求和响应数据的处理流程。它与Flask、Django等Web框架完美集成,是处理JSON数据的理想选择。
安装与配置
使用pip安装Marshmallow非常简单:
pip install marshmallow
安装完成后,你可以在Python文件中导入并使用它:
from marshmallow import Schema, fields
注意: Marshmallow需要Python 3.7或更高版本。建议在虚拟环境中安装以保持项目依赖的隔离。
定义Schema
Schema是Marshmallow的核心概念,它定义了数据序列化和反序列化的规则。每个Schema类对应一种数据类型。
from marshmallow import Schema, fields, validate
class UserSchema(Schema):
id = fields.Int(dump_only=True) # 只用于序列化输出
name = fields.Str(required=True)
email = fields.Email(required=True)
age = fields.Int(
required=True,
validate=validate.Range(min=18, max=120, error="年龄必须在18-120岁之间")
)
created_at = fields.DateTime(dump_only=True)
is_active = fields.Boolean(missing=True) # 默认值
字段类型
- String (Str)
- Integer (Int)
- Boolean (Boolean)
- DateTime
- List (List)
- Nested (嵌套Schema)
常用参数
- required: 字段是否必需
- validate: 验证器函数
- dump_only: 只用于序列化输出
- load_only: 只用于反序列化输入
- missing: 默认值
- error_messages: 自定义错误消息
数据序列化
序列化是将复杂数据类型(如ORM对象)转换为简单数据类型(如字典、JSON)的过程。
from datetime import datetime
# 创建一个用户对象
user = {
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"age": 28,
"created_at": datetime.now(),
"is_active": True
}
# 序列化单个对象
schema = UserSchema()
result = schema.dump(user)
print(result)
# 输出: {'name': '张三', 'email': 'zhangsan@example.com', ...}
# 序列化为JSON
json_result = schema.dumps(user)
print(json_result)
提示: 使用dump_only=True
的字段(如id和created_at)在序列化时会包含在输出中,但在反序列化时会被忽略。
数据反序列化
反序列化是将简单数据类型(如JSON)转换为复杂数据类型的过程,通常用于处理客户端提交的数据。
# 用户提交的数据(通常来自JSON请求)
user_data = {
"name": "李四",
"email": "lisi@example.com",
"age": 25
}
# 反序列化数据
schema = UserSchema()
result = schema.load(user_data)
print(result) # 输出: {'name': '李四', 'email': 'lisi@example.com', 'age': 25, 'is_active': True}
# 从JSON字符串反序列化
json_data = '{"name": "王五", "email": "wangwu@example.com", "age": 30}'
result = schema.loads(json_data)
注意: 反序列化时会自动应用字段验证。如果数据无效,Marshmallow会抛出ValidationError
异常。
数据验证
Marshmallow提供了强大的数据验证功能,确保输入数据符合预期格式和业务规则。
from marshmallow import ValidationError
# 无效的用户数据
invalid_data = {
"name": "赵六",
"email": "invalid-email", # 无效的邮箱格式
"age": 15 # 低于最小年龄
}
try:
result = schema.load(invalid_data)
except ValidationError as err:
print(err.messages)
# 输出:
# {
# 'email': ['Not a valid email address.'],
# 'age': ['年龄必须在18-120岁之间']
# }
内置验证器
- validate.Range: 数值范围验证
- validate.Length: 长度验证
- validate.OneOf: 值在预定义列表中
- validate.Regexp: 正则表达式验证
- validate.URL: URL格式验证
- validate.Email: 邮箱格式验证
嵌套Schema
对于复杂的数据结构,可以使用嵌套Schema来处理关联数据。
class AddressSchema(Schema):
street = fields.Str(required=True)
city = fields.Str(required=True)
country = fields.Str(required=True)
class UserWithAddressSchema(Schema):
id = fields.Int(dump_only=True)
name = fields.Str(required=True)
email = fields.Email(required=True)
address = fields.Nested(AddressSchema) # 嵌套地址Schema
# 使用示例
user_data = {
"name": "钱七",
"email": "qianqi@example.com",
"address": {
"street": "人民路123号",
"city": "上海市",
"country": "中国"
}
}
schema = UserWithAddressSchema()
result = schema.load(user_data)
提示: 使用many=True
参数可以处理对象列表,这在处理多个嵌套对象时非常有用。
发表评论