Heroku上APScheduler定时任务执行后SQLAlchemy修改未提交到数据库
问题排查建议
- 补全Flask应用上下文
单独运行的clock进程没有自动激活Flask应用上下文,你调用的db.session实际未绑定有效数据库连接,提交操作会静默失效。修改定时任务函数,将所有数据库操作包裹在应用上下文管理器中,同时显式添加修改后的对象到会话,避免部分版本ORM未自动追踪变更:
def daily_users_update(): with app.app_context(): # 新增应用上下文声明 for profile in SteamProfiles.query: clear_id = profile.steam_profile_id.replace("http://steamcommunity.com/profiles/", "") status, hours = hours_calculator(clear_id) profile.hours_in_2_weeks = hours db.session.add(profile) print(profile.hours_in_2_weeks) try: db.session.commit() except Exception as e: print(f"提交失败: {str(e)}") db.session.rollback()
- 捕获事务异常
默认情况下APScheduler会吞掉任务执行过程中的未捕获异常,添加上述try-except块可以捕获提交阶段的所有错误,包括数据库连接超时、权限不足、行锁冲突、免费数据库容量超限等问题都会通过异常暴露。 - 验证数据库写入结果
提交完成后可新增查询校验逻辑,确认写入是否生效,排除本地对象缓存误导:
db.session.commit() # 新增校验代码 verify_profile = SteamProfiles.query.get(profile.id) print(f"校验写入结果: {verify_profile.hours_in_2_weeks}")
- 检查Heroku进程与资源限制
- 执行
heroku ps确认clock进程处于running状态,免费层Heroku如果24小时内没有外部请求会休眠所有进程,包括clock进程 - 检查Heroku Postgres免费层的行限制,超出10000行后写入操作会静默失败,可执行
heroku pg:info查看当前使用量 - 确认clock进程的环境变量与web进程一致,尤其是
DATABASE_URL配置是否正确
- 调整提交逻辑
避免单条循环提交,可将所有对象修改完成后统一提交,减少事务冲突概率:
def daily_users_update(): with app.app_context(): for profile in SteamProfiles.query: clear_id = profile.steam_profile_id.replace("http://steamcommunity.com/profiles/", "") status, hours = hours_calculator(clear_id) profile.hours_in_2_weeks = hours db.session.add(profile) # 所有修改完成后统一提交 try: db.session.commit() except Exception as e: print(f"批量提交失败: {str(e)}") db.session.rollback()
内容的提问来源于stack exchange,提问作者banditez
相关产品推荐
相关产品推荐

