FastAPI教程-集成SQLAlchemy:expire_on_commit不要设置为True 作者:马育民 • 2026-08-17 10:18 • 阅读:10001 # 说明 创建引擎时,代码如下: ``` async_session = async_sessionmaker( async_engine, # 绑定数据库引擎 class_=AsyncSession, # 指定会话类,调用 async_session() 返回的类型 expire_on_commit=False ) ``` `expire_on_commit` 的默认值是 `True`,需要将 `expire_on_commit` 设置为 `False` **作用:**执行 `commit` 后,会话中的 **表模型对象** **不过期**,再次访问对象中的属性(即:表中的字段),不需要重新查询数据库 # expire_on_commit 设置为 True 代码修改为: ``` async_session = async_sessionmaker( async_engine, # 绑定数据库引擎 class_=AsyncSession, # 指定会话类,调用 async_session() 返回的类型 expire_on_commit=True ) ``` 或者去掉 `expire_on_commit` 参数 # 测试 修改 `main.py` 文件,内容如下: ``` @app.post('/user') async def save_user(username:str,password:str, db = Depends(get_db)): user = User(username = username,password = password) await save(db,user) # 关键:在 save()中已经执行 commit() 了,之后再访问对象属性会报错 return { "code":200, "msg":f"添加成功!用户id:{user.id}" } ``` **关键:**在 `save()` 中已经执行 `commit()` 了,之后再访问对象属性会报错,如:`user.id` ### 执行测试 [](https://www.malaoshi.top/upload/0/0/1GW3sSaKJvDq.png) ### 报错 [](https://www.malaoshi.top/upload/0/0/1GW3sSq87dKr.png) ### 原因 1. `await save(db, user)` 内部执行 `await db.commit()` 2. 默认 `expire_on_commit=True`,执行 `commit()` 后, `user` 对象标记为 `expired` 过期 3. `return` 里读取 `user.id`,对象过期,SQLAlchemy 尝试自动 `SELECT` 刷新对象 4. `AsyncSession` 不能同步执行数据库 IO,直接抛 `MissingGreenlet` 错误 # 解决 解决方法有若干种,这里用:增加 `await db.refresh(user)` ### 代码 ``` @app.post('/user') async def save_user(username:str,password:str, db = Depends(get_db)): user = User(username = username,password = password) await save(db,user) # commit后再刷新模型对象,会自动查询 await db.refresh(user) return { "code":200, "msg":f"添加成功!用户id:{user.id}" } ``` ### 执行测试 程序能够正确执行,但看控制台,发现 `commit()` 后,又再次执行查询了: [](https://www.malaoshi.top/upload/0/0/1GW3sSuqp2uA.png) # 结论 如果将 `expire_on_commit` 设置为 `True` ,`commit` 后模型对象已经过期,不能再用。 再次访问对象属性(即:表中的字段值),为了避免报错,需要加额外代码,**导致再次查询数据** 所以:`expire_on_commit` 设置为 `False` 原文出处:/show_1GW3sSzhn12P.html