You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drizzle ORM中timestamp.defaultNow()在PlanetScale报错但生效问题

问题分析

你在使用Drizzle ORM创建包含created_at列的users表时,推送schema到PlanetScale出现ER_INVALID_DEFAULT错误,提示created_at默认值无效,但最终表结构(包括索引)却成功同步到了数据库。

错误原因
  1. Vitess校验时机问题:PlanetScale基于Vitess,在执行ALTER TABLE添加索引的操作时,会额外校验表中已有列的默认值合法性。虽然表创建时已经成功生成了created_at列,但后续添加索引的操作触发了Vitess的二次校验,导致抛出错误。
  2. 语法兼容性差异:defaultNow()生成的默认值语法,在Vitess环境下不符合严格校验规则。Vitess对MySQL timestamp类型的默认值处理有细微差异,更倾向于显式的CURRENT_TIMESTAMP写法。
  3. 错误信息误导:错误栈显示的SQL是创建索引的操作,但提示指向created_at,这是因为Vitess执行ALTER操作时会检查表的整体结构,而非仅当前操作的对象。
解决方法

以下是几种可行的修复方案:

1. 显式指定CURRENT_TIMESTAMP表达式

将defaultNow()替换为显式SQL表达式,确保Vitess能正确识别默认值:

createdAt: timestamp('created_at').notNull().default(sql`CURRENT_TIMESTAMP`),

2. 改用datetime类型

如果timestamp的默认值校验问题难以解决,可将created_at改为datetime类型,功能上和timestamp在多数场景下一致,且Vitess对其默认值处理更宽松:

createdAt: datetime('created_at').notNull().defaultNow(),

3. 升级Drizzle Kit版本

检查当前使用的Drizzle Kit版本,升级到最新稳定版,新版本可能已修复和PlanetScale/Vitess的兼容性问题:

npm install drizzle-kit@latest --save-dev
验证结果

修改后重新执行drizzle-kit push:mysql命令,应该不会再出现created_at默认值的错误提示,同时表结构和索引能正常同步。

内容的提问来源于stack exchange,提问作者Parzival

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 12:43:10