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

Flask-SQLAlchemy查询所有记录时如何正确返回JSON格式数据

问题原因

IncomeExpenseModel.query.all() 返回的是由多个IncomeExpenseModel实例组成的列表,不是单个模型对象,你直接对列表调用.orderdate、.who这类仅模型实例才有的属性,必然触发属性错误,导致接口无法正常返回JSON。
单条查询接口用get_or_404(id)拿到的是单个模型实例,所以可以直接读取属性构造返回字典,不存在这个问题。
另外你的模型中income、expense字段是Numeric类型,对应Python的Decimal类型,Flask默认的JSON序列化器不支持该类型,直接返回也会触发序列化报错,需要做类型转换。

修改方案

方案1:直接修改全量接口逻辑

遍历查询返回的对象列表,将每个模型实例手动转为可序列化的字典,同时处理Decimal类型的转换:

@app.route('/incomeexpense/all', methods=['GET'])
def handle_incomexpense_all():
    incomeexpense_list = IncomeExpenseModel.query.all()
    response_list = []
    for item in incomeexpense_list:
        response_list.append({
            "id": item.id,
            "orderdate": item.orderdate,
            "who": item.who,
            "location": item.location,
            "income": float(item.income) if item.income is not None else None,
            "expense": float(item.expense) if item.expense is not None else None
        })
    return {"message": "success", "incomeexpense": response_list}

注:路由已经限定了仅接受GET请求,接口里的request.method == 'GET'判断是冗余代码,可以直接删掉。

方案2:给模型添加序列化方法(推荐)

在模型类中新增统一的to_dict()序列化方法,单条、全量接口可以直接复用,避免重复写字段映射逻辑:

class IncomeExpenseModel(db.Model):
    __tablename__ = 'incomeexpense'

    id = db.Column(db.Integer, primary_key=True)
    orderdate = db.Column(db.String())
    who = db.Column(db.String())
    location = db.Column(db.Integer())
    income = db.Column(db.Numeric(16,2), nullable=True)
    expense = db.Column(db.Numeric(16,2), nullable=True)

    def __init__(self, orderdate, who, location, income, expense):
            self.orderdate = orderdate
            self.who = who
            self.location = location
            self.income = income
            self.expense = expense
    
    # 新增统一序列化方法
    def to_dict(self):
        return {
            "id": self.id,
            "orderdate": self.orderdate,
            "who": self.who,
            "location": self.location,
            "income": float(self.income) if self.income is not None else None,
            "expense": float(self.expense) if self.expense is not None else None
        }

修改后两个接口都可以大幅简化:

  • 单条查询接口
@app.route('/incomeexpense/<id>', methods=['GET'])
def handle_incomexpense(id):
    incomeexpense = IncomeExpenseModel.query.get_or_404(id)
    return {"message": "success", "incomeexpense": incomeexpense.to_dict()}
  • 全量查询接口
@app.route('/incomeexpense/all', methods=['GET'])
def handle_incomexpense_all():
    incomeexpense_list = IncomeExpenseModel.query.all()
    response_list = [item.to_dict() for item in incomeexpense_list]
    return {"message": "success", "incomeexpense": response_list}
额外注意

Flask路由按照注册顺序匹配,固定路径/incomeexpense/all必须写在动态路径/incomeexpense/<id>的前面,否则框架会把路径中的all当成id参数传入单条查询接口,触发404错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:54:23