Flask-SQLAlchemy 查询结果如何转换为 JSON 格式?

Flask-SQLAlchemy 查询结果如何转换为 JSON 格式?
最新回答
心动奶盖

2023-01-28 14:11:59

在使用 Flask-SQLAlchemy 时,虽然框架本身未提供直接的 JSON 转换方法,但可通过以下方式将查询结果高效转换为 JSON 格式:

方法 1:手动序列化(推荐基础场景)

通过遍历模型属性,手动构建字典结构,适用于简单模型或需要定制字段的场景。

from flask import jsonify# 假设模型 User 包含 id、name、email 字段users = User.query.all()result = []for user in users: result.append({ 'id': user.id, 'name': user.name, 'email': user.email })return jsonify(result) # Flask 内置方法,返回 JSON 响应

优点

  • 完全控制输出字段,避免敏感数据泄露。
  • 无需额外依赖,兼容所有 SQLAlchemy 模型。

缺点

  • 代码冗余,需手动维护字段列表。
方法 2:利用模型 __dict__ 或 vars()(需过滤)

通过 vars(obj) 或 obj.__dict__ 获答没取对象属性字典,但需过滤 SQLAlchemy 内部字段(如 _sa_instance_state)。

def model_to_dict(model): return { key: value for key, value in vars(model).items() if not key.startswith('_') # 过滤内部字段 }users = User.query.all()result = [model_to_dict(user) for user in users]return jsonify(result)

优点

  • 代码简洁,自动适配模型字段变化。

缺点

  • 需手动过滤内部字段,可能遗漏特殊情况。
方租御法 3:使用 SQLAlchemy 扩展 marshmallow-sqlalchemy

通过 marshmallow 库定义序列化模式,支持复杂嵌套关系和字段验证。

  1. 安装依赖:pip install marshmallow-sqlalchemy
  2. 定义序列化模式:from marshmallow_sqlalchemy import SQLAlchemyAutoSchemaclass UserSchema(SQLAlchemyAutoSchema): class Meta: model = User load_instance = True # 支持反序列化user_schema = UserSchema(many=True) # many=True 用于序列化列表
  3. 转换数据:users = User.query.all()result = user_schema.dump(users)return jsonify(result)

优点

  • 支持嵌套关系、字段过滤和验证。
  • 代码可复用,适合复杂 API。

缺点

  • 需引入额外依赖,学习成本较高。
方法 4:使用 flask-sqlalchemy 的 json 扩展(Flask 2.0+)

Flask 2.0 及以上版本支持通过 json 模块自动处理 SQLAlchemy 对象,但需手动配置。

from flask import Flaskfrom flask.json import JSONEncoderfrom your_app import db, User # 替换为实际导入路清型纳径class CustomJSONEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, db.Model): # 判断是否为 SQLAlchemy 模型 return { 'id': obj.id, 'name': obj.name # 添加其他字段... } return super().default(obj)app = Flask(__name__)app.json_encoder = CustomJSONEncoder # 替换默认编码器# 使用时直接返回模型对象@app.route('/users')def get_users(): users = User.query.all() return jsonify(users) # 自动调用 CustomJSONEncoder

优点

  • 全局配置,无需逐个处理模型。

缺点

  • 需手动实现所有模型的序列化逻辑。
方法 5:第三方库 sqlalchemy-serializer

安装专用序列化库简化操作:

pip install sqlalchemy-serializer

使用示例:

from sqlalchemy_serializer import SerializerMixin# 修改模型继承 SerializerMixinclass User(db.Model, SerializerMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80)) email = db.Column(db.String(120)) # 可选:指定序列化字段 @property def serialize(self): return { 'id': self.id, 'name': self.name }users = User.query.all()result = [user.serialize for user in users] # 或直接调用 to_dict()return jsonify(result)

优点

  • 开箱即用,支持自定义字段。

缺点

  • 需修改模型继承关系。
总结建议
  • 简单场景:使用方法 1 或方法 2,快速实现且无需额外依赖。
  • 复杂 API:选择方法 3(marshmallow-sqlalchemy),支持嵌套和验证。
  • 全局配置:尝试方法 4(Flask JSON 编码器),适合统一处理。
  • 避免 Peewee:原回答中提到的 peewee.model_to_dict 仅适用于 Peewee 模型,与 SQLAlchemy 不兼容,不可直接使用

通过以上方法,可灵活选择最适合项目需求的 JSON 转换方案。