FastAPI使用sqlalchemy_mptt创建分类时lft字段非空约束报错如何解决
问题解决指南
错误根因
sqlalchemy_mptt依赖SQLAlchemy ORM的事件回调机制,自动计算填充嵌套集合结构必需的lft、rgt、level字段。你当前使用的Category.__table__.insert()属于SQLAlchemy Core层语法,完全绕开了ORM层的事件监听逻辑,mptt无法自动生成字段值,就会触发非空约束报错。- 现有插入逻辑存在参数传递错误:
parent_id存在的分支没有传入parent_id参数,反而空parent_id的根节点分支传递了parent_id,逻辑完全写反。
修复方案
1. 改用ORM对象方式执行插入
不要使用Core层的insert语法,改为实例化Category ORM对象,通过session提交操作,触发mptt的自动计算逻辑:
from sqlalchemy import select async def resolve_create_category(db, data, parent_id): # 校验分类是否已存在 exist_category = await db.execute( select(Category).where(Category.title == data.title) ).scalar_one_or_none() if exist_category: return CategoryCreatePayload( category=None, errors=[ Error( code="CATEGORY_ALREADY_EXIST", message=f"Category with title {data.title} already exist", ) ], ) # 实例化ORM对象,自动处理parent_id category = Category( title=data.title, description=data.description, parent_id=parent_id if parent_id else None ) # 通过ORM session提交 db.add(category) await db.commit() await db.refresh(category) # 刷新获取自动生成的id、lft、rgt等字段 return CategoryCreatePayload(category=category)
2. 确认表结构完整性
如果你没有使用迁移工具自动生成表,需要确认category表已经存在lft、rgt、parent_id、level四个mptt必需字段,不需要你手动在模型中定义,BaseNestedSets已经自动内置了这些字段。
3. 根节点处理规范
根节点的parent_id直接传None即可,不要传0,否则mptt会尝试查找id为0的父分类,触发不存在的报错。
内容的提问来源于stack exchange,提问作者Serenity
相关产品推荐
相关产品推荐

