快速结论:该报错发生在 Dify 自托管环境下,当通过 ORM 更新 TriggerProviderSubscription、AppTriggerSubscription、AppTrigger、WorkflowTriggerLog、WorkflowTriggerStatus 等模型的记录时,updated_at 字段不会自动刷新(始终保持原值)。优先排查 api/models/trigger.py 文件中 6 个 updated_at 列是否错误地使用了 server_onupdate=func.current_timestamp(),应替换为 onupdate=func.current_timestamp()。
问题场景
在 Dify 自托管(Source)环境中运行主分支代码,通过 ORM 操作触发相关的服务(如 api/services/trigger/*、schedule_service.py、webhook_service.py 等)进行更新后,发现 updated_at 字段长时间未变化,可能影响依赖该时间戳的业务逻辑(如缓存失效、同步检查等)。
报错原文
# api/models/trigger.py 中 6 个 affected columns 的错误模式
server_default=func.current_timestamp(),
server_onupdate=func.current_timestamp(), # typo: server_onupdate expects FetchedValue, not a Python callable
# 正确的写法(该文件中 line 534 已正确使用)
onupdate=func.current_timestamp()
原因分析
在 SQLAlchemy ORM 中,server_onupdate= 参数期望接收一个 FetchedValue 对象(用于标记数据库侧由触发器/默认值更新的列),而非常见的 func.current_timestamp() 这样的 Python 可调用对象。SQLAlchemy 会静默接受 func.current_timestamp() 作为 server_onupdate 的值,但不会在 ORM 执行 UPDATE 语句后自动刷新该列的值,导致 updated_at 永远停留在插入时的原始值。这是 api/models/trigger.py 中 6 个列独有的类型错误,代码库其他 70+ 个模型均统一使用 onupdate=func.current_timestamp()。
环境排查
- 确认使用的是 Dify main branch(uncommitted)版本。
- 确认部署模式为 Self Hosted(Source)。
- 检查
api/models/trigger.py文件中的updated_at列声明:line 128、183、213、373、433、482。
解决步骤
- 打开
api/models/trigger.py文件。 - 定位到受影响的 6 个
updated_at列(行号参考:128、183、213、373、433、482)。 - 将每个列声明中的
server_onupdate=func.current_timestamp()替换为onupdate=func.current_timestamp()。 - 对于
AppTrigger.updated_at(line 482),将server_onupdate=naive_utc_now()替换为onupdate=naive_utc_now(),保持 Python 侧模式一致。 - 保留
server_default=func.current_timestamp()不变,确保 INSERT 行为不受影响。 - 无需执行数据库迁移,因为该变更仅影响 ORM 层面的 Python 钩子,不改变 DDL 列定义。
验证方法
修改代码后,通过 ORM 更新任意受影响模型的记录(例如调用 session.commit() 后),检查 updated_at 字段是否自动刷新为当前时间。也可以在更新前记录时间戳,更新后重新查询该记录,确认 updated_at 与更新操作的时间匹配。该修复不影响直接通过 SQL 语句进行的更新。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


