使用 Drizzle ORM 创建 bigint 自增主键(Identity Column)完整指南
文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载在使用 Drizzle ORM 操作 PostgreSQL 时如何为表定义一个既具备bigint数据类型、又使用现代 identity column 机制自动生成的主键本文基于 drizzle/create-bigint-identity-column-for-primary-key.md 展开给出可直接运行的 TypeScript 表定义、drizzle-kit generate生成的真实迁移 SQL并结合本仓库中关于迁移日志与插入返回值的相关笔记帮你彻底掌握这一常见建模场景。完整示例定义一张带 bigint 自增主键的表假设我们要创建一张users表主键id使用 PostgreSQL 的bigint类型并通过 identity column 让数据库自动生成主键值。在 Drizzle 中完整定义如下import { pgTable, bigint, text, timestamp, } from drizzle-orm/pg-core; // Users table export const users pgTable(users, { id: bigint({ mode: bigint }).primaryKey().generatedAlwaysAsIdentity(), email: text(email).unique().notNull(), name: text(name).notNull(), createdAt: timestamp(created_at).defaultNow().notNull(), });这段代码的核心在于id这一列的链式调用导入bigint从drizzle-orm/pg-core中导入bigint用于声明这一列的数据类型为 PostgreSQL 的bigint指定主键通过.primaryKey()将id声明为表的主键声明自增语义通过.generatedAlwaysAsIdentity()将默认值语义声明为generated always as identity即主键值由数据库侧的 identity 机制自动生成。为什么bigint必须指定mode这是本示例中最容易踩坑的一点bigint必须显式传入mode配置否则运行时会抛出如下错误TypeError: Cannot read properties of undefined (reading mode)原因是 Drizzle 中的bigint()需要依赖mode来决定该列在 JavaScript / TypeScript 侧的序列化方式mode: bigint该列的值在查询结果中会被还原为 JavaScript 的BigInt类型适合表示超出Number.MAX_SAFE_INTEGER9007199254740991范围的整数mode: number该列的值会被还原为 JavaScript 的Number类型适合范围在安全整数之内的场景。由于 PostgreSQL 的bigint是 8 字节有符号整数取值范围为-9223372036854775808到9223372036854775807参见仓库笔记 postgres/integers-in-postgres.md上限远超过 JSNumber的安全范围。因此当主键可能增长到较大数值时mode: bigint是更稳妥的选择。选择number模式虽然代码上可行但需要你自行确保取值不会溢出安全整数范围。生成的迁移 SQLdrizzle-kit generate 的产物当表结构定义好后运行迁移生成命令npx drizzle-kit generateDrizzle 会根据 schema 生成对应的 SQL 迁移文件其中会包含类似如下的建表语句-- statement-breakpoint CREATE TABLE IF NOT EXISTS users ( id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name users_id_seq INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1), email text NOT NULL, name text NOT NULL, created_at timestamp DEFAULT now() NOT NULL, CONSTRAINT users_email_unique UNIQUE(email) );这份 SQL 可以逐项与上面的 TypeScript 定义对上号TypeScript 声明生成的 SQL 片段说明bigint({ mode: bigint })id bigint列数据类型为bigint8 字节有符号整数.primaryKey()PRIMARY KEY列被声明为表的主键.generatedAlwaysAsIdentity()GENERATED ALWAYS AS IDENTITY (sequence name users_id_seq INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1)由数据库自动生成主键值并自动创建配套的序列users_id_seqtext(email).unique().notNull()email text NOT NULLCONSTRAINT users_email_unique UNIQUE(email)非空且唯一text(name).notNull()name text NOT NULL非空timestamp(created_at).defaultNow().notNull()created_at timestamp DEFAULT now() NOT NULL默认取当前时间且非空注意 identity 子句中的参数INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1。这里的MAXVALUE 9223372036854775807恰好就是bigint类型的最大值上限说明 PostgreSQL 为该 identity 列自动生成的序列直接对齐了bigint的完整取值范围。为什么用 identity column 而不是 serial主键自增在历史上最流行的写法是serial或bigserial。本仓库的 postgres/generate-modern-primary-key-columns.md 专门讨论了这一问题PostgreSQL 官方 wiki 明确建议新应用不要使用serial而应使用 identity columns原因是 serial 类型在 schema、依赖和权限管理上存在一些绕不开的怪异行为。因此.generatedAlwaysAsIdentity()映射到的GENERATED ALWAYS AS IDENTITY正是当前推荐的现代做法。与之相对Drizzle 也提供了.generatedByDefaultAsIdentity()对应 SQL 中的GENERATED BY DEFAULT AS IDENTITY二者的区别在于GENERATED ALWAYS AS IDENTITY应用无法显式写入该列的主键值除非使用OVERRIDING SYSTEM VALUE保证值完全由数据库生成GENERATED BY DEFAULT AS IDENTITY允许应用在插入时显式提供该列的值仅在未提供时由数据库生成。对于不希望业务代码干预主键生成的场景本示例采用的ALWAYS语义是更严格、更安全的选择。结合迁移与插入流程的完整实战闭环定义好 identity 主键只是第一步把整个流程串起来还需要理解两件事迁移如何被跟踪以及插入后如何拿回数据库自动生成的id。迁移文件如何被记录运行npx drizzle-kit generate生成 SQL 迁移文件后还需要运行npx drizzle-kit migrate将其应用到数据库。仓库笔记 drizzle/drizzle-tracks-migrations-in-a-log-table.md 说明Drizzle 会像其他 SQL 迁移工具一样在数据库中使用一张日志表默认名为__drizzle_migrations位于drizzleschema 下记录每个迁移文件的 SHA256 哈希和运行时间戳从而判断哪些迁移已经执行、哪些还没有执行。所以上述建表 SQL 一旦被migrate应用就会被登记在这张日志表中后续重复运行不会再次执行。插入后获取自动生成的主键值由于id由数据库侧的 identity 机制生成普通的insert返回值是QueryResultnever拿不到任何有用的数据。仓库笔记 drizzle/get-fields-for-inserted-row.md 给出了标准解法在 insert 语句后追加.returning()让 PostgreSQL 返回插入行的全部字段如果只需要新行的id还可以做部分返回await db .insert(users) .values({ email, name, }) .returning({ id: users.id })这两篇仓库内的相关笔记分别对应 drizzle/drizzle-tracks-migrations-in-a-log-table.md 与 drizzle/get-fields-for-inserted-row.md与本文主题共同构成定义 identity 主键 → 生成并应用迁移 → 插入并回读主键的完整实战链路。小结本文围绕 Drizzle ORM PostgreSQL 的bigintidentity 主键覆盖了从 TypeScript 表定义、mode参数的必要性、drizzle-kit generate生成的迁移 SQL 解读到现代 identity column 相对serial的优势以及迁移跟踪与插入返回值两个相邻环节。掌握这一组合你就可以放心地为新表设计大规模、数据库自主生成的主键并让 Drizzle 的 schema 定义、迁移与运行时查询保持一致。更多相关主题可继续阅读仓库中的 Drizzle 分类 与 PostgreSQL 分类 笔记。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐drizzle-orm-pg 0.15.1PostgreSQL Schema模式完整支持与使用指南drizzle orm pg 0.15.1PostgreSQL Schema模式完整支持与使用指南 导读 本文以 drizzle orm pg 0.15.后端数据库ORMRufus 制作U盘启动盘指南3 步做出能开机的U盘老电脑也适用Rufus 制作U盘启动盘指南3 步做出能开机的U盘老电脑也适用 插上U盘、选好镜像、点了开始进度条走到一半报错或者做完电脑根本不认盘。Rufus 是一桌面应用开发工具Drizzle ORM 0.27.1 新增 Neon HTTP 驱动支持在 Serverless 环境中使用 drizzle-orm/neon-httpDrizzle ORM 0.27.1 新增 Neon HTTP 驱动支持在 Serverless 环境中使用 drizzle orm/neon http dr后端数据库ORM上一篇Mac Mouse Fix系统更新后鼠标功能异常完整修复指南诊断、修复、预防全攻略下一篇3步打造专业Golang终端应用从开发到分发的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

MCP协议实现AI自主读取功耗数据的技术实践

MCP协议实现AI自主读取功耗数据的技术实践

1. 项目概述:为什么需要让 AI “自己看” 功耗计? “让 AI 自己看功耗计”——这句话乍听像科幻设定,但落到 IoT 工程现场,它其实是一句极其务实的工程宣言。我第一次在产线调试边缘网关时,就卡在了这个环节&#xff…

2026/10/4 1:51:35 阅读更多 →
Android内置RTSP服务器:实现局域网低延迟视频推流与播放

Android内置RTSP服务器:实现局域网低延迟视频推流与播放

做局域网视频传输的朋友一定有过这种憋屈时刻:临时想把手机摄像头画面投到会议大屏,或者把一台设备的摄像头画面共享给局域网里几台机器同时看,结果发现不是得装一堆App,就是绕道公网平台,延迟高还受网络限制。于是我就…

2026/10/4 1:51:35 阅读更多 →
Apache Fesod(Incubating) Fesod Sheet 快速上手:一个示例玩转 Excel 读写

Apache Fesod(Incubating) Fesod Sheet 快速上手:一个示例玩转 Excel 读写

后端 【免费下载链接】fesod Fast. Easy. Done. Processing spreadsheets without worrying about large files causing OOM. 项目地址: https://gitcode.com/gh_mirrors/fast/fesod 点击查看 免费下载 Apache Fesod(Incubating) 的 fesod-sheet 模块提供了一套以 …

2026/10/4 1:51:35 阅读更多 →

最新新闻

InfiniBand Vol 1 深度解析:报文协议、传输服务与排障陷阱

InfiniBand Vol 1 深度解析:报文协议、传输服务与排障陷阱

简介:InfiniBand架构卷1的Release 1.7最终版官方规范,面向高性能计算、数据中心与存储网络领域的架构师、工程师及研究人员。文档完整收录1.0至1.7的版本修订历史与更新说明,在1.6基础上新增网络探测(Network Probe)An…

2026/10/4 2:23:00 阅读更多 →
MRAM替代EEPROM:伺服驱动器高频掉电数据记录方案详解

MRAM替代EEPROM:伺服驱动器高频掉电数据记录方案详解

前阵子做一台伺服驱动器的数据记录改造,原来的方案在板上放了颗EEPROM存运行参数,调试时发现三个问题同时冒出来:写入一次要几个毫秒,电机关断时序窗口根本等不及;频繁记录的累计运行时间把寿命打到极限;中…

2026/10/4 2:23:00 阅读更多 →
MRAM替代Flash:TM4C129与MR25H40CDF工业数据存储方案详解

MRAM替代Flash:TM4C129与MR25H40CDF工业数据存储方案详解

做工业设备这几年,真正让我头疼的往往不是算法和通信协议,而是最不起眼的“存数据”。之前做一个电力参数记录模块,用MCU内部Flash频繁改写参数,设备运行一年半以后,写入时间越来越长,最后干脆写不进去——…

2026/10/4 2:23:00 阅读更多 →
MRAM + PIC18F86J16:工业数据采集不掉电的可靠存储方案

MRAM + PIC18F86J16:工业数据采集不掉电的可靠存储方案

做工业数据采集类产品,最怕的就是现场突然断电。早几年我做一台故障录波终端,用SPI Nor Flash记录波形,测试时连续拔插电源,间隔只有几十毫秒,结果Flash里整块整块的数据损坏,有些扇区连读出都是0xFF。后来…

2026/10/4 2:22:59 阅读更多 →
MRAM替代Flash:MR25H40CDF+STM32F446RE工业存储实战

MRAM替代Flash:MR25H40CDF+STM32F446RE工业存储实战

做工业嵌入式这些年,只要涉及数据存储,大家默认就是 SPI NOR Flash 或者 EEPROM。但有一类场景特别尴尬:频繁写日志、掉电瞬间抢存关键参数、或者数据需要保持十几年不丢。Flash 有写次数限制和块擦除延迟,EEPROM 容量又实在太小&…

2026/10/4 2:22:58 阅读更多 →
UHFReader09 C# Demo 调试实战:从串口通信到 EPC 盘存

UHFReader09 C# Demo 调试实战:从串口通信到 EPC 盘存

简介:这是一份面向C#开发者与RFID入门者的UHF RFID阅读器演示工程,围绕UHFReader09设备展开,帮助读者理解如何用C#与UHF频段读写器通信、处理标签数据并控制频段、功率、识别速率等参数,可迁移到仓储管理、物流追踪、资产盘点等场…

2026/10/4 2:21:58 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:35 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →