Django调用模型save方法保存修改后数据未同步到数据库如何解决?
问题排查与解决方案
- 事务未提交/回滚
如果你的save_run函数被包裹在@transaction.atomic装饰的代码块中,或者上层调用逻辑手动开启了事务,一旦代码块内出现未捕获的异常,就会触发事务回滚,你的修改不会同步到数据库。部分自定义事务配置也可能关闭了自动提交,导致修改暂存未落盘。
解决方法:
- 检查上层调用逻辑是否有事务包裹,确认没有未捕获的异常触发回滚
- 临时添加显式提交测试,确认问题是否属于事务类问题:
from django.db import transaction def save_run(run_id: str, model, train_score: float, validation_score: float): run: Run = Run.objects.get(id=run_id) run.train_score = train_score run.validation_score = validation_score run.save() transaction.commit() # 仅测试用,正常自动提交场景不需要手动写
- 自定义save方法/pre_save信号拦截
如果你覆写了Run模型的save方法,或者为Run绑定了pre_save信号处理器,逻辑存在缺陷时会拦截保存操作:比如自定义save方法中没有调用父类的super().save(*args, **kwargs),或者pre_save信号处理器返回了False终止了保存流程。
解决方法:
- 检查
Run模型是否有自定义的save方法,确认父类save方法被正确调用 - 检查项目中是否有针对
Run的pre_save信号绑定,临时注释相关逻辑测试是否正常保存
- 数据库路由/权限/读写分离问题
如果你的项目配置了读写分离,可能存在写入操作被路由到只读从库,或者主从同步延迟导致你查询的从库数据没有更新;另外如果数据库账号只有查询权限、没有修改权限,部分驱动配置下可能不会抛出明显报错。
解决方法:
直接使用QuerySet的update方法测试,绕过实例save流程:
def save_run(run_id: str, model, train_score: float, validation_score: float): updated_count = Run.objects.filter(id=run_id).update(train_score=train_score, validation_score=validation_score) print(updated_count) # 如果输出为1说明更新生效,为0说明没有匹配到记录
如果update方法可以正常更新数据,说明问题出在实例save的流程中;如果update也不生效,检查数据库账号权限、DATABASES路由配置是否正确。
- 并发修改覆盖
如果有其他异步任务、线程同时操作同一条Run记录,可能在你save之后,其他逻辑又把字段值改回了旧值。
解决方法:
查询时添加行锁避免并发修改:
from django.db import transaction @transaction.atomic def save_run(run_id: str, model, train_score: float, validation_score: float): # 加行锁,其他事务会等待当前事务完成再操作这条记录 run: Run = Run.objects.select_for_update().get(id=run_id) run.train_score = train_score run.validation_score = validation_score run.save(update_fields=["train_score", "validation_score"])
内容的提问来源于stack exchange,提问作者Gabriel Milan
相关产品推荐
相关产品推荐

