完整指南)
文档教程知识库【免费下载链接】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),仅供参考