flask---》Marshmallow介绍及基础使用

article/2025/10/31 5:09:03

0. Marshmallow背景介绍

介绍

  • Marshmallow,中文译作:棉花糖。
  • 是一个轻量级的数据格式转换的模块,也叫序列化和反序列化模块,常用于将复杂的orm模型对象与python原生数据类型之间相互转换。
  • 一般用于flask
  • marshmallow提供了丰富的api功能。如下:
  1. Serializing

    序列化[可以把数据对象转化为可存储或可传输的数据类型,例如:objects/object->list/dict,dict/list->string]

  2. Deserializing

    反序列化器[把可存储或可传输的数据类型转换成数据对象,例如:list/dict->objects/object,string->dict/list]

  3. Validation

    数据校验,可以在反序列化阶段,针对要转换数据的内容进行类型验证或自定义验证。

官方文档:

marshmallow: simplified object serialization — marshmallow 3.15.0 documentationhttps://marshmallow.readthedocs.io/en/latest/

1. 使用

1. 安装

pip3 install -U marshmallow-sqlalchemy -i https://pypi.douban.com/simple
pip3 install -U flask-sqlalchemy -i https://pypi.douban.com/simple
pip3 install -U flask-marshmallow -i https://pypi.douban.com/simple
pip3 install -U pymysql -i https://pypi.douban.com/simple

2. flask连接mysql介绍 

# 格式
"mysql://用户名:密码@ip:端口/库名称?charset=utf8mb4"# 案例
"mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"

3. 模块初始化:

from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from datetime import datetimeimport pymysqlpymysql.install_as_MySQLdb()
# 实例化app = Flask(__name__)# 配置数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 实例化
db = SQLAlchemy()
ma = Marshmallow()
# 注册
db.init_app(app)
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")username = db.Column(db.String(255), index=True, comment="用户名")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(15), index=True, comment="手机号码")sex = db.Column(db.Boolean, default=True, comment="性别")email = db.Column(db.String(255), index=True, comment="邮箱")created_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")updated_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")def __repr__(self):return "<%s: %s>" % (self.__class__.name, self.username)@app.route("/")
def index():return "hello"if __name__ == '__main__':with app.app_context():# db.drop_all()db.create_all()app.run(debug=True, host='127.0.0.1', port=7800)

4. Marshmallow序列化基础使用

  • 只有4.1是完整的代码,其他的只提供Marshmallow的代码,初始化的代码,就不在重复写了

schema常用属性数据类型

类型描述
fields.Dict(keys, type]] = None, values, …)字典类型,常用于接收json类型数据
fields.List(cls_or_instance, type], **kwargs)列表类型,常用于接收数组数据
fields.Tuple(tuple_fields, *args, **kwargs)元组类型
fields.String(*, default, missing, data_key, …)字符串类型
fields.UUID(*, default, missing, data_key, …)UUID格式类型的字符串
fields.Number(*, as_string, **kwargs)数值基本类型
fields.Integer(*, strict, **kwargs)整型
fields.Decimal(places, rounding, *, allow_nan, …)数值型
fields.Boolean(*, truthy, falsy, **kwargs)布尔型
fields.Float(*, allow_nan, as_string, **kwargs)浮点数类型
fields.DateTime(format, **kwargs)日期时间类型
fields.Time(format, **kwargs)时间类型
fields.Date(format, **kwargs)日期类型
fields.Url(*, relative, schemes, Set[str]]] = None, …)url网址字符串类型
fields.Email(*args, **kwargs)邮箱字符串类型
fields.IP(*args[, exploded])IP地址字符串类型
fields.IPv4(*args[, exploded])IPv4地址字符串类型
fields.IPv6(*args[, exploded])IPv6地址字符串类型
fields.Method(serialize, deserialize, **kwargs)基于Schema类方法返回值的字段
fields.Function(serialize, Any], Callable[[Any, …)基于函数返回值得字段
fields.Nested(nested, type, str, Callable[[], …)外键类型

Schema数据类型的常用通用属性

属性名描述
default序列化阶段中设置字段的默认值
missing反序列化阶段中设置字段的默认值
validate反序列化阶段调用的内置数据验证器或者内置验证集合
required设置当前字段的必填字段
allow_none是否允许为空 None,""
load_only是否在反序列化阶段才使用到当前字段,相当于之前的write_only
dump_only是否在序列化阶段才使用到当前字段,相当于之前的read_only
error_messages字典类型,可以用来替代默认的字段异常提示语,格式: error_messages={“required”: “用户名为必填项。”}

单个表模型序列化成字典或json字符串

  • 代码
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from datetime import datetimeimport pymysqlpymysql.install_as_MySQLdb()
# 实例化app = Flask(__name__)# 配置数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 实例化
db = SQLAlchemy()
ma = Marshmallow()
# 注册
db.init_app(app)
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")username = db.Column(db.String(255), index=True, comment="用户名")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(15), index=True, comment="手机号码")sex = db.Column(db.Boolean, default=True, comment="性别")email = db.Column(db.String(255), index=True, comment="邮箱")created_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")updated_time = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")def __repr__(self):return "<%s: %s>" % (self.__class__.name, self.username)# marshmallow转换数据格式主要通过架构转换类来完成.
# 在marshmallow使用过程中所有的架构转换类必须直接或间接继承于Schema基类
# 导入基类Schema--->继承 fields--->字段
from marshmallow import Schema, fields# 类似与django的from组件
class UserSchema(Schema):username = fields.String()mobile = fields.String()email = fields.Email()create_time = fields.DateTime()@app.route("/")
def index():# 模拟数据user = User(username="xiaoming",mobile="13312345677",sex=True,email="133123456@qq.com",created_time=datetime.now(),updated_time=datetime.now())# 调用marsh把模型转换成python基本数据格式[字典/列表]us = UserSchema()# 转换成字典ret1 = us.dump(user)# 转换成json字符串(它是双引号的)ret2 = us.dumps(user)print(">>>> 原生  --> 对象")print(User)print(">>>> us.dump(user)  --> 字典")print(ret1)print(">>>> us.dumps(user) --> json字符串")print(ret2)return "hello"if __name__ == '__main__':with app.app_context():# db.drop_all()db.create_all()app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
>>>> 原生  --> 对象
<class '__main__.User'>
>>>> us.dump(user)  --> 字典
{'username': 'xiaoming', 'mobile': '13312345677', 'email': '133123456@qq.com'}
>>>> us.dumps(user) --> json字符串
{"username": "xiaoming", "mobile": "13312345677", "email": "133123456@qq.com"}

多个表模型序列化成字典或json字符串

  • 代码
# marshmallow转换数据格式主要通过架构转换类来完成.
# 在marshmallow使用过程中所有的架构转换类必须直接或间接继承于Schema基类
# 导入基类Schema--->继承 fields--->字段
from marshmallow import Schema, fields# 类似与django的from组件
class UserSchema(Schema):username = fields.String()mobile = fields.String()email = fields.Email()create_time = fields.DateTime()@app.route("/")
def index():# 模拟数据user = User(username="xiaoming",mobile="13312345677",sex=True,email="133123456@qq.com",created_time=datetime.now(),updated_time=datetime.now())user1 = User(username="xiaoming1号",mobile="13312345677",sex=True,email="133123456@qq.com",created_time=datetime.now(),updated_time=datetime.now())user2 = User(username="xiaoming2号",mobile="13312345677",sex=True,email="133123456@qq.com",created_time=datetime.now(),updated_time=datetime.now())user_list = [user, user1, user2]us = UserSchema()data_list = us.dump(user_list, many=True)print(data_list)return "hello"if __name__ == '__main__':with app.app_context():# db.drop_all()db.create_all()app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
[
{'username': 'xiaoming', 'mobile': '13312345677', 'email': '133123456@qq.com'},
{'username': 'xiaoming1号', 'mobile': '13312345677', 'email': '133123456@qq.com'}, 
{'username': 'xiaoming2号', 'mobile': '13312345677', 'email': '133123456@qq.com'}
]

5. 高级使用

序列化嵌套

  • 代码
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from datetime import datetimeimport pymysqlpymysql.install_as_MySQLdb()
# 实例化app = Flask(__name__)# 配置数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:foobared@106.14.42.253:3308/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 实例化
db = SQLAlchemy()
ma = Marshmallow()
# 注册
db.init_app(app)
ma.init_app(app)# marshmallow转换数据格式主要通过架构转换类来完成.
# 在marshmallow使用过程中所有的架构转换类必须直接或间接继承于Schema基类
# 导入基类Schema--->继承 fields--->字段
from marshmallow import Schema, fields, ValidationError, validates_schema, validates, validate"""
模拟表类型
User表中有两个外键 friends/books
Blog 有一个外键 author
"""class User(object):def __init__(self, name, email):self.name = nameself.email = emailself.created_at = datetime.now()self.books = []self.friends = []class Blog(object):def __init__(self, title, author):self.title = titleself.author = author  # 用来代替MySQL中的外键关系class BlogSchema(Schema):title = fields.String()# 使用lambda匿名函数,使只有在使用author时才会找UserSchema对象,不然可能出现先后调用,导致对象找不到的情况出现# 用来序列化外键对象,可以将外键对象按照指定的格式进行序列化,并且外键指定的格式可以完成任何支持的marshmallow操作author = fields.Nested(lambda: UserSchema())class UserUserSchema(Schema):name = fields.String()email = fields.String()class UserSchema(Schema):name = fields.String()email = fields.Email()created_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S')# 双向嵌套,例如找出所有属于该用户的所有书籍。注意:在大数据量时,数据返回将非常慢books = fields.List(fields.Nested(BlogSchema(exclude=("author",))))# friends = fields.Nested(UserUserSchema(many=True)) # 方式一:使用一个外部的图式,可以指点序列化哪些字段friends = fields.Nested("self", only=("name",), many=True)  # 方式二:使用自身图式作为外键的方式,并指定序列化的字段# friends = fields.Nested(lambda: UserSchema(many=True, only=("name",)), dump_only=True) # 方式二的一种:使用自身图式作为外键的图式,并指定序列化的字段# friends = fields.Pluck("self", "name", many=True) # 方式三:使用Pluck字段可以用单个值来替换嵌套的数据。@app.route("/")
def index():try:user0 = User(name="南派三叔", email="sanshu@163.com")user1 = User(name="刘慈欣", email="sanshu@163.com")user2 = User(name="天下霸唱", email="sanshu@163.com")blog = Blog(title="盗墓笔记", author=user0)res1 = BlogSchema().dump(blog)# print(res, type(res))print(res1)user0.books = [blog]user0.friends.append(user1)user0.friends.append(user2)res2 = UserSchema().dump(user0)print(res2)except Exception as err:print(err)return "hello"if __name__ == '__main__':with app.app_context():# db.drop_all()db.create_all()app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
{'author': {'name': '南派三叔', 
'friends': [],'created_at': '2022-04-09 14:04:05', 'email': 'sanshu@163.com', 
'books': []}, 
'title': '盗墓笔记'
}{'name': '南派三叔', 
'friends': [{'name': '刘慈欣'}, {'name': '天下霸唱'}],'created_at': '2022-04-09 14:04:05', 'email': 'sanshu@163.com', 
'books': [{'title': '盗墓笔记'}]
}

反序列化

  • 代码
from flask import Flask
from flask_marshmallow import Marshmallowapp = Flask(__name__)ma = Marshmallow()
# 注册
ma.init_app(app)# 反序列化
from marshmallow import Schema, fields, validate, ValidationErrorclass UserSchema(Schema):# Str<--->Stringname = fields.Str(validate=validate.Length(min=1))permission = fields.Str(validate=validate.OneOf(["read", "write", "admin"]))age = fields.Int(validate=validate.Range(min=18, max=40))@app.route("/")
def index():user_data = {"name": "Ronnie", "age": 18, "permission": "admin"}schema = UserSchema()result = schema.load(user_data)print(result, type(result))  # => <User: 'Ronnie'>return "hello"if __name__ == '__main__':app.run(debug=True, host='127.0.0.1', port=7800)
  • 输出
{'age': 18, 'name': 'Ronnie', 'permission': 'admin'}

反序列化时转换/忽略部分数据

class UserSchema(Schema):name = fields.String(required=True)age = fields.Integer(required=True)@app.route("/")
def index():result = UserSchema().load({"age": 42}, partial=("name",))print(result)  # => {'age': 42}return "ok"

设置字段只在序列化或反序列化阶段才启用

class UserSchema(Schema):name = fields.Str()# password is password = fields.Str(load_only=True) # 相当于只写字段 "write-only"created_time = fields.DateTime(dump_only=True) # 相当于只读字段 "read-only"

反序列化阶段的钩子方法

post_dump([fn,pass_many,pass_original]) 注册要在序列化对象后调用的方法,它会在对象序列化后被调用。
post_load([fn,pass_many,pass_original]) 注册反序列化对象后要调用的方法,它会在验证数据之后被调用。pre_dump([fn,pass_many]) 注册要在序列化对象之前调用的方法,它会在序列化对象之前被调用。
pre_load([fn,pass_many]) 在反序列化对象之前,注册要调用的方法,它会在验证数据之前调用。

案例

from datetime import datetime
from flask import Flask
from flask_marshmallow import Marshmallow
from marshmallow import Schema,fields,validate,post_dump,post_load,pre_dump,pre_load
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)ma = Marshmallow()
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")name = db.Column(db.String(255), index=True, comment="用户名")age = db.Column(db.Integer, comment="年龄")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(20), comment="手机号")created_time = db.Column(db.DateTime, default=datetime.now, comment="创建时间")def __repr__(self):return "<%s: %s>" % (self.__class__.__name__, self.name)class UserSchema(Schema):name = fields.String(validate=validate.Length(min=1))age = fields.Integer(required=True)password = fields.Str(load_only=True) # 相当于只写字段 "write-only"# created_time = fields.DateTime(dump_only=True) # 相当于只读字段 "read-only"created_time = fields.DateTime(format='%Y-%m-%d %H:%M:%S')mobile = fields.String()@pre_loaddef pre_load(self,data,**kwargs):"""反序列化的前置钩子,会在数据验证之前执行"""data["created_time"] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')return data@post_loaddef post_load(self,data,**kwargs):"""反序列化钩子方法"""data["password"] = generate_password_hash(data["password"])return User(**data)@post_dumpdef post_dump(self,data,**kwargs):"""序列化钩子方法"""data["number"] = 1000data["mobile"] = data["mobile"][:3]+"****"+data["mobile"][-4:]return data@app.route("/")
def index():user_data = {"name": "小明", "age": 20,"password":"123456","mobile":"13312345678"}  # 报错us = UserSchema()# 反序列化instance = us.load(user_data)print(instance) # <User: 小明>print(instance.created_time) # <User: 小明># 序列化data = us.dump(instance)print(data)return "hello"if __name__ == '__main__':app.run(debug=True,host="0.0.0.0",port=5999)

反序列化阶段对数据进行验证

基于内置验证器进行数据验证

内置验证器描述
validate.Email(*, error)邮箱验证
validate.Equal(comparable, *, error)判断值是否相等
validate.Length(min, max, *, equal, error)值长度/大小验证
validate.OneOf(choices, labels, *, error)选项验证
validate.Range([min, max])范围验证
validate.Regexp(regex, bytes, Pattern][, flags])正则验证
validate.URL(*, relative, schemes, Set[str]]] = None, …)验证是否为URL

 案例:内置验证器主要写在字段选项中,代码:

from datetime import datetime
from flask import Flask
from flask_marshmallow import Marshmallow
from marshmallow import Schema,fields,validate,post_dump,post_load,pre_dump,pre_load
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)ma = Marshmallow()
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")name = db.Column(db.String(255), index=True, comment="用户名")email = db.String(db.String(255))age = db.Column(db.Integer, comment="年龄")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(20), comment="手机号")def __repr__(self):return "<%s: %s>" % (self.__class__.__name__, self.name)class UserSchema(Schema):name = fields.String(validate=validate.Length(min=1))age = fields.Integer(required=True,validate=validate.Range(min=16,max=100))email = fields.String(validate=validate.Email())password = fields.Str(load_only=True,validate=validate.Length(min=6,max=16)) # 相当于只写字段 "write-only"mobile = fields.String(validate=validate.Regexp("^1[3-9]\d{9}$",error="手机号格式不正确!"))@app.route("/")
def index():user_data = {"email":"xiaoming@qq.com","name": "小明", "age": 20,"password":"123456","mobile":"13312345678"}  # 报错us = UserSchema()# 反序列化instance = us.load(user_data)print(instance)return "hello"if __name__ == '__main__':app.run(debug=True,host="0.0.0.0",port=5999)

自定义验证方法

通过context或者构造器实例对象进行参数传递

import random
from datetime import datetime
from flask import Flask
from flask_marshmallow import Marshmallow
from marshmallow import Schema,fields,validate,validates,validates_schema,ValidationError,post_load,pre_load
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)ma = Marshmallow()
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")name = db.Column(db.String(255), index=True, comment="用户名")email = db.String(db.String(255))age = db.Column(db.Integer, comment="年龄")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(20), comment="手机号")def __repr__(self):return "<%s: %s>" % (self.__class__.__name__, self.name)class UserSchema(Schema):name = fields.String()age = fields.Integer()email = fields.String()password = fields.Str() # 密码password2 = fields.String() # 确认密码mobile = fields.String(validate=validate.Regexp("^1[3-9]\d{9}$",error="手机号格式不正确!"))# 针对单个指定字段的值进行验证@validates("mobile")def validate_mobile(self,mobile):if(mobile == "13312345678"):raise ValidationError("手机号已经被注册!!")return mobile# 针对多个字段的验证@validates_schemadef validate(self,data,**kwargs):if(data["password"] != data["password2"]):# 注意:验证失败以后,一定是raise抛出异常!!!不能是return!!!!raise ValidationError(field_name="password2",message="密码和确认密码不一致!")return data@post_loaddef post_load(self,data,**kwargs):"""反序列化验证后的钩子方法"""print("num=%s" % self.num)print(self.context)del data["password2"] # 删除掉不必要的字段return User(**data)@app.route("/")
def index():user_data = {"email":"xiaoming@qq.com","name": "小明", "age": 20,"password":"123456","mobile":"13312345671","password2": "123456"}num = random.randint(1,100)# 如果将来在开发中有部分数据需要传递到构造器中进行调用,可以在实例化构造器时通过context传递参数进行,在构造器内部通过self.context调用us = UserSchema(context={"num":num})# 如果将来在开发中有部分数据需要传递到构造器中进行调用,可以作为构造器对象的属性进行传递us.num = num# 反序列化instance = us.load(user_data)print(instance)return "hello"if __name__ == '__main__':app.run(debug=True,host="0.0.0.0",port=5999)

6. 模型构造器

官方文档:

GitHub - marshmallow-code/marshmallow-sqlalchemy: SQLAlchemy integration with marshmallowhttps://github.com/marshmallow-code/marshmallow-sqlalchemy

marshmallow-sqlalchemy — marshmallow-sqlalchemy 0.28.0 documentationhttps://marshmallow-sqlalchemy.readthedocs.io/en/latest/

  • 注意:flask_marshmallow在0.12.0版本以后已经移除了ModelSchema和TableSchema这两个模型构造器类,官方转而推荐了使用SQLAlchemyAutoSchema和SQLAlchemySchema这2个类,前后两者用法类似。
  • 模型构造器实际上是Schema的子类,所以前面所学习的自定义构造器字段,验证器,验证方法,钩子方法等等都可以写进来一起使用。

基于SQLAlchemySchema创建模型构造器

from flask import Flask
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)ma = Marshmallow()
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")name = db.Column(db.String(255), nullable=False, index=True, comment="用户名")email = db.String(db.String(255))age = db.Column(db.Integer, comment="年龄")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(20), comment="手机号")def __repr__(self):return "<%s: %s>" % (self.__class__.__name__, self.name)# 用法1:通过SQLAlchemySchema创建构造器,通过auto从模型中提取字段类型和选项
from marshmallow_sqlalchemy import SQLAlchemySchema,auto_field
from marshmallow import fields,validate
class UserSchema(SQLAlchemySchema):"""模型构造器"""id = auto_field()name = auto_field()password = auto_field()# auto_field在使用过程中,除了可以复制模型对应字段的信息和数据类型以外,我们也可以增加补充说明mobile = auto_field(required=True,validate=validate.Regexp("^1[3-9]\d{9}$"))password2 = fields.String()class Meta:model = User    # 模型类名 table = models.Album.__table__load_instance = True   # 反序列化阶段时,直接返回模型对象include_relationships = True  # 输出模型对象时同时对外键,是否也一并进行处理include_fk = True  # 序列化阶段是否也一并返回主键@app.route("/")
def index():user_data = {"name": "小明","mobile":"13"}us = UserSchema()instance = us.load(user_data,session=db.session)print(instance)return "hello"if __name__ == '__main__':with app.app_context():db.drop_all()db.create_all()app.run(debug=True,host="0.0.0.0",port=5999)

基于SQLAlchemyAutoSchema创建模型构造器(常用)

class 构造器类名(SQLAlchemyAutoSchema):class Meta:model = 模型类名    # table = models.Album.__table__include_relationships = True  # 输出模型对象时同时对外键,是否也一并进行处理include_fk = True # 序序列阶段是否也一并返回主键load_instance = True  # 反序列化阶段时,直接返回模型对象sqla_session = db.session # 数据库连接会话对象# fields= ["id","name"] # 启动的字段列表exclude = ["id","name"] # 排除字段列表

案例

from flask import Flask
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"]="mysql://root:123@127.0.0.1:3306/mofangapp?charset=utf8mb4"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy()
db.init_app(app)ma = Marshmallow()
ma.init_app(app)class User(db.Model):__tablename__ = "tb_user"id = db.Column(db.Integer, primary_key=True, comment="主键ID")name = db.Column(db.String(255), nullable=False, index=True, comment="用户名")email = db.String(db.String(255))age = db.Column(db.Integer, comment="年龄")password = db.Column(db.String(255), comment="登录密码")mobile = db.Column(db.String(20), comment="手机号")def __repr__(self):return "<%s: %s>" % (self.__class__.__name__, self.name)# 用法1:通过SQLAlchemySchema创建构造器,通过auto从模型中提取字段类型和选项
from marshmallow_sqlalchemy import SQLAlchemySchema,auto_field,SQLAlchemyAutoSchema
from marshmallow import fields,validateclass UserSchema(SQLAlchemyAutoSchema):mobile = auto_field(required=True, validate=validate.Regexp("^1[3-9]\d{9}$"))password2 = fields.String(required=True)class Meta:model = User    # 模型类名 table = models.Album.__table__load_instance = True   # 反序列化阶段时,直接返回模型对象include_relationships = True  # 输出模型对象时同时对外键,是否也一并进行处理include_fk = True  # 序列化阶段是否也一并返回主键sqla_session = db.session # 构造器操作数据库的会话对象# fields = ["id","name","mobile","password2"] # 构造器启用的字段列表exclude = ["id","name"] # 构造器禁用的字段列表@app.route("/")
def index():user_data = {"mobile":"13312341234","password2":"1234546"}us = UserSchema()instance = us.load(user_data)print(instance)return "hello"if __name__ == '__main__':with app.app_context():db.drop_all()db.create_all()app.run(debug=True,host="0.0.0.0",port=5999)


http://chatgpt.dhexx.cn/article/FSxSu7Kg.shtml

相关文章

YApi接口平台-接口挡板

YApi是一个开源的平台&#xff0c;官方平台链接&#xff0c;如下https://hellosean1025.github.io/yapi/index.html,目前很多大公司在使用&#xff0c;主要优势我认为有2个&#xff0c;第一该平台开源&#xff0c;搭建方便&#xff1b;第二该平台解决了前后端分离开发的痛点&am…

open source HTML 5移动应用 -Exlive 人员定位客户端(BlackBerry 10, Android, iPhone)

下图是exlive人员定位系统的宣传页&#xff0c;其官方主站在这里 www.exlive.cn 下图是BlackBerry OS 7.0上面的运行效果&#xff0c;更多截图见这里 http://blog.csdn.net/berryreload/article/details/8099674 Update: Remove BlackBerry OS 7.0支持 升级到PhoneGap 3.0&…

My BlackBerry

什么是黑莓 RIM公司成立于1984年。 黑莓手机&#xff08;Blackberry&#xff09;&#xff0c;是指由加拿大Reserach In Motion&#xff08;RIM&#xff09;公司推出的一种无线手持邮件解决终端设备&#xff0c;也就是我们平时称的手机。 2013年1月30日&#xff0c;RIM公司今…

解决联网下载服务端返回405问题

最近遇到了一个问题&#xff0c;在项目中有一个启动页广告图片下载的功能&#xff0c;之前能够正常下载&#xff0c;由于这个版本遇到了运营商DNS劫持的问题&#xff0c;服务端要调整图片的下载路径&#xff0c;也就是改变了图片的链接地址。修改地址之后下载就出现异常了&…

IIS 405 Method Not Allowed

今天将项目发布到IIS上后&#xff0c;发现Delete方法用不了&#xff0c;可进行如下设置&#xff1a; 打开处理程序映射 找到WebDAV点击请求限制&#xff0c;勾选全部谓词 这个方法如果无效的话 方法二&#xff1a;因为是WebDAVModule限制的请求&#xff0c;所以直接将WebDAV…

前端请求接口时报405错误

他说方法不存在 他的问题所在就是没有找到后端对应的接口 意思就是说没有找到我后端put这个对应的接口 我记得写了不知道为啥没了纳闷

IIS put请求 报HTTP Error 405 - Method Not Allowed

在新的服务器上部署了一个.net core的项目&#xff0c;部分请求地址使用了put、delete方式&#xff0c;导致无法正常请求&#xff0c;报Error 405 - Method Not Allowed。 由于配置IIS时把“WebDAV 发布”给勾选了&#xff0c;所以会导致拦截。 服务器和IIS 10配置如下图&…

405 Method Not Allowed 解决方案

背景描述 前端发送请求到后端&#xff0c;可是经过swagger测试&#xff0c;后端接口是没问题的 可是一旦调用就发生405报错 解决方案 一般这种情况发生是因为前后端请求方式不一致 写在前端的接口声明方式是post 我们来看后端 很明显了&#xff0c;后端是get&#xff0c;因…

405 Method Not Allowed(亲测,实用)

今天在发布一个网站的时候遇到 标题上的问题&#xff0c;一直不明白是为何&#xff0c;刚开始以为是我的程序写的有问题&#xff0c;随即将项目发给同事来发布试试&#xff0c;在他的IIS上发布却没出现问题&#xff0c;一切正常&#xff0c;这可就怪了&#xff0c;于是想到了应…

宝塔面板数据库出现405 Not Allowed 错误的原因和解决办法

我们在网站建设和网站维护过程中&#xff0c;除了云服务器需要小心维护之外&#xff0c;还要应对突然出现的一些问题&#xff0c;比如今天网站突然打不开了&#xff0c;根据页面提示&#xff0c;貌似是数据库的原因&#xff0c;于是登录宝塔面板&#xff0c;想要看看数据库怎么…

浏览器页面报错405!

首先看浏览器的报错页面 后端控制台正常 可以明显的看出是因为我们提交的method是不被允许的&#xff0c;这就说明是我们的 请求方式的问题&#xff0c;常见的请求方式有 post,get.大家如果不知道自己默认的请求方式是get或者post,我们可以在继承HttpServlet的时候继承doGet(),…

html405是什么错误,网站打开显示405错误信息如何解决?

当我们打开网页时候&#xff0c;会显示404,405,500等报错信息&#xff0c;下面海站格给大家介绍常见的405报错时的处理方法&#xff1a; IIS 返回 405 - 不允许用于访问此页的 HTTP 谓词。终极解决办法!!!! 1、为什么会出现这个错误? 我们可以理解为在当前IIS服务器上&#xf…

一款ModbusRTU/TCP485串口协议调试软件工具绿色版免安装

软件的界面如下&#xff1a; 支持modbus设备的读写操作&#xff0c;把设备地址、功能码、寄存器地址、寄存器个数都显示出来了&#xff0c;浅析易懂&#xff0c;很适合初学者和工程师对modbus设备进行调试、测试。 一款好用的modbus调试大师助手软件工具操作演示&#xff0c;…

“405”报错解决方案

405是什么意思&#xff1f; 意思如下&#xff1a; “405”经常作为“Method Not Allowed”的缩写来使用&#xff0c;中文中表示&#xff1a;“不允许的方法”。 英文缩写词&#xff1a;405 英文单词&#xff1a;Method Not Allowed 缩写词分类&#xff1a;Internet 缩写词…

2.Modbus通信协议-软件调试4个工具软件(推荐)

Modbus通信协议-软件调试的4个工具软件 1.Launch Virtual Serial Port Driver 2.Modbus Poll 3.Modbus Slave 4.UartAssist 软件下载 以下为官网下载链接&#xff1a; Virtual Serial Port Driver Modbus Slave和Modbus Poll UartAssist 1.Virtual Serial Port Driver …

矩阵的迹规则

A为一个方阵&#xff0c;则Tr A表示A的迹&#xff08;就是主对角线上各项的和&#xff09;&#xff0c; 在量子力学中,Tr为迹,(trace),A,B,C为矩阵,证明:(1).Tr(AB)Tr(BA) ; (2).Tr(ABC)Tr(BCA)Tr(CAB) 第一个公式直接把(AB)ii的表达式写出来,然后求和,很容易证明与(BA)ii的…

矩阵的迹(Tr)

迹运算返回的是矩阵对角元素的和: 若不使用求和符号&#xff0c;有些矩阵运算很难描述&#xff0c;而通过矩 阵乘法和迹运算符号可以清楚地表示。例如&#xff0c;迹运算提供了另一种描述矩阵Frobenius范数的方式: 用迹运算表示表达式&#xff0c;我们可以使用很多有用的等式巧…

计算矩阵的迹

关于矩阵的迹和它的性质&#xff0c;可以参考下面这篇文章。 矩阵的迹及相关性质 这里想运用矩阵迹的性质&#xff0c;计算下面这个矩阵的迹: 式子中假设是单位矩阵&#xff0c;是矩阵&#xff0c;那么根据矩阵迹的循环置换(cyclic permutation)性质: 根据矩阵迹的加法性质&a…

矩阵的迹及其一些定理证明

再写最小二乘法多元线性回归矩阵求导的时候用到了矩阵的迹和一些定理&#xff0c;特此在这里推导下 矩阵迹的定义: 一个nxn矩阵A的迹是指A主对角线上各元素的总和&#xff0c;记做tr(A) 定理&#xff1a; tr(AB) tr(BA) 定理&#xff1a; 证明如下 定理: 证明如下: