首页
/ Drizzle ORM 中 $onUpdate 与 SQL 表达式结合使用的注意事项

Drizzle ORM 中 $onUpdate 与 SQL 表达式结合使用的注意事项

2025-05-06 14:17:13作者:魏侃纯Zoe

概述

在使用 Drizzle ORM 进行数据库操作时,开发者经常会遇到需要在记录更新时自动设置时间戳的需求。虽然 Drizzle 提供了 $onUpdate$onUpdateFn 这样的便捷方法,但在与 SQL 表达式结合使用时存在一些需要注意的技术细节。

问题现象

许多开发者尝试使用以下方式定义时间戳字段:

updatedAt: timestamp('updated_at')
  .notNull()
  .$onUpdateFn(() => sql`now()`)

但在实际执行更新操作时,会抛出 TypeError: value.toISOString is not a function 的错误。这是因为 Drizzle ORM 在运行时处理这些带有 $ 前缀的方法时,期望返回的是 JavaScript 的 Date 对象,而不是原始的 SQL 表达式。

技术原理

Drizzle ORM 中的 $onUpdate$onUpdateFn 是纯粹的运行时功能,它们不会影响数据库的实际 schema。这些方法:

  1. 只在 JavaScript 运行时环境中生效
  2. 不能直接嵌入 SQL 表达式
  3. 期望返回的是 JavaScript 可处理的值(如 Date 对象)

解决方案

方案一:使用字符串模式

updatedAt: timestamp('updated_at', {
  withTimezone: true,
  mode: 'string'  // 关键设置
})
.defaultNow()
.notNull()
.$onUpdate(() => sql`now()`)

这种方法通过将字段模式设置为 string,绕过了 Date 对象的类型检查,但返回的是字符串而非 Date 对象。

方案二:自定义时间处理函数

function getCurrentTimeInTimeZoneISO(timeZone: string) {
  const now = Date.now();
  const zonedDate = toZonedTime(now, timeZone);
  zonedDate.toISOString = () => format(zonedDate, "yyyy-MM-dd'T'HH:mm:ss'Z'", { timeZone })
  return zonedDate
}

// 使用
updatedAt: timestamp("updated_at")
.$onUpdate(() => getCurrentTimeInTimeZoneISO('America/Sao_Paulo'))

这种方法通过自定义 Date 对象的 toISOString 方法,提供了更灵活的时间处理能力。

最佳实践

  1. 对于简单场景,直接返回 new Date()
  2. 需要数据库服务器时间时,考虑在应用层处理
  3. 需要时区支持时,使用专门的时区处理库
  4. 文档中的示例需要谨慎对待,部分示例可能不适用于所有场景

总结

理解 Drizzle ORM 中运行时方法与数据库 schema 的区别至关重要。虽然 $onUpdate 系列方法提供了便利,但它们与直接 SQL 表达式的结合存在限制。开发者应根据实际需求选择合适的实现方式,平衡便利性与功能需求。

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
136
187
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
884
524
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
363
381
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
182
264
kernelkernel
deepin linux kernel
C
22
5
nop-entropynop-entropy
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
7
0
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.09 K
0
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
84
4
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
614
60
open-eBackupopen-eBackup
open-eBackup是一款开源备份软件,采用集群高扩展架构,通过应用备份通用框架、并行备份等技术,为主流数据库、虚拟化、文件系统、大数据等应用提供E2E的数据备份、恢复等能力,帮助用户实现关键数据高效保护。
HTML
120
79