如何使用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
相关产品推荐
相关产品推荐

