Flask Marshmallow SqlAlchemy使用Pluck时出现JSON序列化错误
使用Marshmallow Pluck字段序列化关联模型时出现JSON序列化错误
我有两个关联的SQLAlchemy模型(Product和TechnologyPillar),尝试用Marshmallow的Pluck字段在ProductSchema中返回关联的TechnologyPillar的特定字段,但序列化时抛出错误:TypeError: Object of type TechnologyPillar is not JSON serializable。移除technology_pillar字段时能正常返回数据,只要包含该字段就报错。
模型代码
from datetime import datetime from typing import List from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class TechnologyPillar(db.Model): __tablename__ = "product_technology_pillars" id: db.Mapped[int] = db.mapped_column(primary_key=True) technology_pillar: db.Mapped[str] = db.mapped_column(db.String(150), nullable=False, unique=True) active_record: db.Mapped[bool] = db.mapped_column(db.Boolean) product: db.Mapped[List["Product"]] = db.relationship(back_populates="technology_pillar") def __repr__(self) -> str: return f"TechnologyPillar(id={self.id!r}, technology_pillar={self.technology_pillar!r})" class Product(db.Model): __tablename__ = "products" id: db.Mapped[int] = db.mapped_column(primary_key=True) name: db.Mapped[str] = db.mapped_column(db.String(150), nullable=False, unique=True) fk_pillar_id = db.mapped_column(db.ForeignKey('product_technology_pillars.id')) technology_pillar: db.Mapped["TechnologyPillar"] = db.relationship(back_populates="product", lazy='joined', innerjoin=True) active_record: db.Mapped[bool] = db.mapped_column(db.Boolean, nullable=False) created_date: db.Mapped[datetime] = db.mapped_column(db.DateTime, default=datetime.utcnow) modified_date: db.Mapped[datetime] = db.mapped_column(db.DateTime, default=datetime.utcnow) def __repr__(self) -> str: return f"Product(" \ f"id={self.id!r}, name={self.name!r})"
Schema代码(原错误版本)
from flask_marshmallow import Marshmallow ma = Marshmallow() class TechnologyPillarSchema(ma.SQLAlchemyAutoSchema): class Meta: fields = ("id", "technology_pillar") class ProductSchema(ma.SQLAlchemyAutoSchema): class Meta: technology_pillar = ma.Pluck(TechnologyPillarSchema, 'technology_pillar') fields = ("id", "name", "technology_pillar")
主程序代码
from flask import Flask, jsonify from flask_sqlalchemy import SQLAlchemy from products.models import Product, TechnologyPillar from products.schemas import ProductSchema, TechnologyPillarSchema app = Flask(__name__) db = SQLAlchemy(app) technology_pillar_schema = TechnologyPillarSchema() technologies_pillars_schema = TechnologyPillarSchema(many=True) product_schema = ProductSchema() products_schema = ProductSchema(many=True) @app.route('/<id>', methods=['GET']) def singleProduct(id): stmt = db.select(Product).where(Product.id == id) single_product = db.session.scalars(stmt).first() return product_schema.jsonify(single_product)
解决方案
错误的核心原因是Pluck字段的定义位置错误:你把technology_pillar = ma.Pluck(...)放在了Meta类内部,而Marshmallow只会识别Schema类直接定义的字段,Meta类仅用于配置Schema的元数据(比如fields、model等)。
修改后的ProductSchema应该把Pluck字段移到Meta类外部:
class ProductSchema(ma.SQLAlchemyAutoSchema): # 直接在Schema类下声明Pluck字段 technology_pillar = ma.Pluck(TechnologyPillarSchema, 'technology_pillar') class Meta: fields = ("id", "name", "technology_pillar")
这样修改后,Marshmallow会正确使用Pluck字段提取关联的TechnologyPillar对象的technology_pillar字段值,而不是直接序列化整个对象,就能避免JSON序列化错误。
另外,你的模型中已经通过lazy='joined'配置了关联对象的即时加载,所以不需要额外处理关联数据的加载问题,确保序列化时能获取到关联对象。
内容的提问来源于stack exchange,提问作者Justin Kelley
相关产品推荐
相关产品推荐

