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

如何使用SQLAlchemy向JSONB类型的字典列表字段中新增字典

SQLAlchemy 向JSONB数组追加字典解决方案

问题原因

你的代码存在两个核心问题:

  • 逻辑错误:user.details本身就是存储字典的列表,你遍历了列表中的字典元素,尝试调用字典不存在的append()方法,根本无法往列表中添加新元素
  • 变更检测失效:SQLAlchemy默认无法主动检测JSONB这类可变类型的内部修改,就算你正确修改了列表,也可能出现commit后数据库没有更新的问题

修复方案

方案1:Python层面修改(适合需要先读取对象做其他逻辑的场景)

from sqlalchemy.orm.attributes import flag_modified

class Models(Base):
    __tablename__ = 'Table'
    id = Column(Integer, primary_key=True)
    details = Column(JSONB, nullable=False, server_default='[]')


@router.post("/post2")
async def post2(id: int = 1):
    session = Session()
    user = session.query(Models).filter(Models.id == id).first()
    # 直接对details列表追加新字典,不需要遍历
    user.details.append({"b": "200"})
    # 手动标记details字段已修改,触发SQLAlchemy的更新逻辑
    flag_modified(user, "details")
    session.commit()
    # 刷新对象获取数据库最新存储的值
    session.refresh(user)
    return user

方案2:数据库层面直接更新(适合仅更新字段的场景,性能更高)

不需要先查询对象再修改,直接执行更新语句,减少一次数据库查询开销:

from sqlalchemy import func

class Models(Base):
    __tablename__ = 'Table'
    id = Column(Integer, primary_key=True)
    details = Column(JSONB, nullable=False, server_default='[]')


@router.post("/post2")
async def post2(id: int = 1):
    session = Session()
    # 调用PostgreSQL的jsonb_insert函数直接往数组末尾追加元素
    session.query(Models).filter(Models.id == id).update({
        "details": func.jsonb_insert(
            Models.details,
            "{-1}", # 占位符表示插入到数组最后一个位置
            {"b": "200"}
        )
    }, synchronize_session=False)
    session.commit()
    # 查询最新结果返回
    user = session.query(Models).filter(Models.id == id).first()
    return user

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:15:02