首页
/ Drizzle ORM 处理 PostgreSQL 中 LOCALTIMESTAMP 默认值的正确方式

Drizzle ORM 处理 PostgreSQL 中 LOCALTIMESTAMP 默认值的正确方式

2025-05-06 01:10:56作者:秋泉律Samson

在数据库开发中,为时间戳字段设置默认值是一个常见需求。PostgreSQL 提供了标准的 SQL 函数 LOCALTIMESTAMP 来获取当前时间戳,但如何在 Drizzle ORM 中正确处理这一默认值呢?

问题背景

当使用 Drizzle ORM 的 introspection 功能从 PostgreSQL 数据库生成模式定义时,如果表中有使用 LOCALTIMESTAMP 作为默认值的字段,生成的模式文件会出现问题。具体表现为:

  1. 原始 SQL 表定义:
CREATE TABLE test (
  test TIMESTAMP WITHOUT TIME ZONE DEFAULT LOCALTIMESTAMP
);
  1. 生成的模式文件:
export const test = pgTable("test", {
  test: timestamp({ mode: 'string' }).default(LOCALTIMESTAMP),
});
  1. 尝试推送此模式时会出现错误:
ReferenceError: LOCALTIMESTAMP is not defined

解决方案

正确的做法是使用 Drizzle ORM 提供的 sql 标签来包装 PostgreSQL 函数调用:

test: timestamp({ mode: 'string' }).default(sql`LOCALTIMESTAMP`),

技术原理

Drizzle ORM 需要明确区分 JavaScript 运行时环境和 SQL 表达式。LOCALTIMESTAMP 是一个 SQL 函数,而不是 JavaScript 变量或函数。通过使用 sql 标签,我们告诉 Drizzle 这是一个需要原样传递到 SQL 查询中的表达式,而不是在 JavaScript 环境中求值的代码。

最佳实践

  1. 对于所有 PostgreSQL 内置函数作为默认值的情况,都应使用 sql 标签
  2. 在手动编写模式定义时,注意区分 JavaScript 和 SQL 上下文
  3. 定期更新 Drizzle ORM 和相关工具,以确保获得最新的修复和改进

版本说明

这个问题在 Drizzle ORM 0.37 和 Drizzle Kit 0.29 版本中已得到修复。新版本能够正确识别 LOCALTIMESTAMP 等 SQL 函数,并在生成的模式文件中自动添加 sql 标签。

通过理解这一机制,开发者可以更好地处理数据库模式与 ORM 之间的映射关系,避免类似的引用错误问题。

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