You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python+Flask+Marshmallow开发API遇<Object id>无法JSON序列化问题

解决Flask+Marshmallow中SQLAlchemy对象无法JSON序列化的问题

我一眼就看出你碰到的是SQLAlchemy模型实例直接返回时的序列化坑——当你尝试把User模型对象直接丢给jsonify()或者返回给客户端时,Flask自带的JSON编码器根本不知道怎么处理这些带着数据库连接属性的对象,直接就抛出<Object id> is not JSON serializable错误了。

结合你现有的代码,给你一步步的解决方案:

1. 先把User模型补全

看你代码里sta...应该是没写完的状态字段?先把模型定义完整,比如:

class User(db.Model):
    userid = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30))
    badgenum = db.Column(db.String(30))
    mail = db.Column(db.String(30))
    status = db.Column(db.String(10), default='active')  # 可根据实际需求调整
    created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)

2. 给User模型配个Marshmallow Schema

Marshmallow就是专门干序列化这事儿的,能把SQLAlchemy对象转成JSON能识别的纯字典结构。你可以选自动生成或手动定义两种方式:

自动生成Schema(推荐,省事儿)

class UserSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = User  # 指定对应的SQLAlchemy模型
        load_instance = True  # 允许从字典反向生成模型实例,后续做POST/PUT请求时有用
        include_fk = False  # 不需要外键的话设为False

# 初始化schema实例:单个用户用user_schema,多个用户列表用users_schema
user_schema = UserSchema()
users_schema = UserSchema(many=True)

手动定义Schema(适合需要自定义字段的场景)

class UserSchema(ma.Schema):
    userid = fields.Integer()
    name = fields.String()
    badgenum = fields.String()
    mail = fields.String()
    status = fields.String()
    created_at = fields.DateTime()

3. 在视图函数里用Schema序列化对象

你之前肯定是直接返回了模型实例,比如这样:

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get(user_id)
    return jsonify(user)  # 这里直接传模型对象必报错!

正确的姿势是先用Marshmallow的dump()方法把对象转成纯字典,再传给jsonify():

@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get_or_404(user_id)  # 用get_or_404更友好,找不到直接返回404
    # 用schema把模型对象序列化成字典
    serialized_user = user_schema.dump(user)
    return jsonify(serialized_user)

# 如果是返回用户列表
@app.route('/users', methods=['GET'])
def get_users():
    all_users = User.query.all()
    serialized_users = users_schema.dump(all_users)
    return jsonify(serialized_users)

4. 额外优化:处理DateTime字段的格式(可选)

如果你的模型里有DateTime字段,默认序列化后是ISO格式字符串,要是你想改成更友好的格式(比如YYYY-MM-DD HH:MM:SS),可以在Schema里指定:

class UserSchema(ma.SQLAlchemyAutoSchema):
    # 自定义DateTime字段的格式化
    created_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
    class Meta:
        model = User
        load_instance = True

最后说下为啥会报错

SQLAlchemy的模型实例不是普通的Python字典,它内部藏着数据库会话、延迟加载这些额外属性,Flask默认的JSON编码器只能处理字符串、数字、列表、字典这些基础类型,根本搞不定这些带数据库属性的对象。所以必须通过Marshmallow把对象转换成纯字典结构,才能被JSON正常序列化。

内容的提问来源于stack exchange,提问作者JeanSec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:16:31