Next.js + Drizzle ORM 全流程终极指南
·
📖 目录
- 🏗️ 全局架构逻辑图 (新增)
- 前置准备:依赖安装
- 核心配置:drizzle.config.ts (必填项检查)
- 环境与安全:.env 与 .gitignore
- TypeScript 增强:tsconfig.json 路径别名
- 定义模型:db/schema.ts (类型生成的源头)
- ✨ 核心实战:类型推导与数据插入 (含流程图)
- 完整工作流验证
- 常见问题与避坑指南
1. 🏗️ 全局架构 (新增)
在写代码之前,我们先看一张图,理解 Drizzle ORM 是如何连接 代码、配置 和 数据库 的。
💡 图解关键点:
- 左侧 (定义层):
schema.ts是唯一的真理来源(Single Source of Truth)。它不仅定义表,还通过$inferInsert自动生成 了NewUser类型。 - 中间 (配置层):
drizzle.config.ts负责桥接,它读取.env找到数据库,并告诉工具去哪里找schema.ts。 - 右侧 (执行层):CLI 工具根据配置生成 SQL 并更新数据库;而你的业务代码则利用生成的
NewUser类型,确保传给数据库的数据是安全的。
2. 前置准备:依赖安装
确保安装了运行时库、开发工具库以及类型定义。
# 1. 核心运行时库
npm install drizzle-orm postgres
# 2. 开发工具库 (生成迁移用)
npm install -D drizzle-kit dotenv
# 3. TypeScript 类型定义
npm install -D @types/node
3. 核心配置:drizzle.config.ts (必填项检查)
此文件位于项目根目录。必须包含 dotenv 加载和环境变量校验。
import { defineConfig } from "drizzle-kit";
import * as dotenv from "dotenv";
// 【必填】加载 .env
dotenv.config({ path: ".env" });
if (!process.env.DATABASE_URL) {
throw new Error("❌ 错误: .env 中缺少 DATABASE_URL");
}
export default defineConfig({
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL!, // 非空断言
},
schema: "./db/schema.ts", // ⚠️ 必须对应实际路径
out: "./drizzle", // 迁移文件输出目录
verbose: true,
strict: true,
});
4. 环境与安全:.env 与 .gitignore
.env 文件
DATABASE_URL="postgresql://postgres:你的密码@localhost:5432/my_nextjs_db?schema=public"
.gitignore 文件
确保包含:
.env
.node_modules
.next
5. TypeScript 增强:tsconfig.json 路径别名
为了让导入更优雅(如 @/db/schema),配置 paths。
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"],
"@/db": ["./db"],
"@/db/*": ["./db/*"]
}
}
}
6. 定义模型:db/schema.ts (类型生成的源头)
这是所有 TypeScript 类型的来源。
文件路径: db/schema.ts
import { pgTable, text, serial, timestamp } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(), // 自增主键
name: text("name").notNull(), // 必填
email: text("email").unique(), // 唯一
createdAt: timestamp("created_at").defaultNow(), // 默认当前时间
});
// 💡 显式导出类型
// 1. 查询返回的类型 (全量字段)
export type User = typeof users.$inferSelect;
// 2. 插入数据的类型 (自动排除自增和默认值字段)
export type NewUser = typeof users.$inferInsert;
7. ✨ 核心实战:类型推导与数据插入 (含流程图)
这一步展示了 NewUser 类型如何在代码中发挥作用。
🔄 类型推导微观流程
💻 代码实战
创建一个测试文件(例如 test-insert.ts):
import { type NewUser } from "@/db/schema";
// ✅ 正确示范:只需关注业务必填字段
const newUser: NewUser = {
name: "Alice",
email: "alice@example.com",
// TS 智能提示:id 和 createdAt 不需要传,因为它们有默认值/自增
};
// ❌ 错误示范 1:漏传必填字段 (TS 会红线报错)
// const badUser1: NewUser = { email: "bob@example.com" };
// 报错信息: Property 'name' is missing...
// ❌ 错误示范 2:传了不该传的字段 (TS 会红线报错)
// const badUser2: NewUser = { ..., id: 123 };
// 报错信息: Object literal may only specify known properties, and 'id' does not exist...
console.log("✅ 类型检查通过!数据准备就绪:", newUser);
// --- 实际插入逻辑 ---
// import { db } from "@/db";
// import { users } from "@/db/schema";
// await db.insert(users).values(newUser);
💡 为什么这很重要?
- 编译期拦截:在代码运行前,TypeScript 就已经帮你挡掉了 90% 的数据库字段错误。
- 智能提示:输入
newUser.时,IDE 只会显示name和email,界面清爽,不再被id、updatedAt等系统字段干扰。 - 重构友好:如果数据库改了(比如
email变为必填),所有使用该类型的地方都会立即报错提示你修改。
8. 完整工作流验证
结合图表逻辑,跑通全流程:
- 生成迁移 (读取 Config & Schema -> 生成 SQL):
npx drizzle-kit generate - 执行迁移 (执行 SQL -> 更新 DB):
失效时可以用npx drizzle-kit migrate
$env:PGPASSWORD='密码'; & "C:\Program Files\PostgreSQL\17\bin\psql.exe" -h localhost -p 5432 -U postgres -d my_first_nextjs_db -f "./db/migrations/第一步生成的sql文件"
- 类型检查 (验证代码是否符合 Schema 类型):
✅ 无报错 = 类型安全通关npx tsc --noEmit - 运行测试:
npx tsx test-insert.ts
9. 常见问题与避坑指南
| 问题 | 原因 | 解决方案 |
|---|---|---|
Cannot find module '@/db/schema' |
TS 路径未生效 | 检查 tsconfig.json,重启 VS Code TS 服务。 |
Property 'id' is missing |
误用了 $inferSelect |
插入用 $inferInsert (NewUser),查询用 $inferSelect (User)。 |
process.env.DATABASE_URL is undefined |
config 文件没加载 env | 确保 drizzle.config.ts 顶部有 dotenv.config()。 |
TS 提示 id 不是可选的 |
Schema 定义问题 | 检查 id 是否加了 .primaryKey(),Drizzle 依赖此标记来推断可选性。 |
10. 核心概念解析
在开始动手之前,我们需要明确今天涉及的四个关键角色及其关系:
| 组件 | 角色比喻 | 作用 |
|---|---|---|
| PostgreSQL Server | 仓库管理员 | 真正存储数据的地方。它是一个后台服务,负责接收指令、保存数据、保证数据安全。 |
| pgAdmin 4 | 仓库可视化大屏 | 图形化管理工具。让你不用敲黑底白字的命令,通过点击鼠标就能查看表结构、浏览数据、执行 SQL。 |
| Drizzle ORM | 翻译官/中介 | 位于你的 Next.js 代码和数据库之间。你写的是 TypeScript/JavaScript 代码,Drizzle 把它“翻译”成数据库能听懂的 SQL 语句。 |
.env 文件 |
门禁卡/钥匙 | 存储敏感信息(如数据库密码、连接地址)。绝对不能上传到 GitHub,是连接代码与数据库的唯一凭证。 |
11. 环境准备与安装流程 (Windows 版
2. 环境准备与安装流程 (Windows 版)
2.1 下载官方安装包
我们采用“一站式”安装策略,一个安装包同时解决数据库和管理工具。
- 下载地址:PostgreSQL Windows Installer
- 选择版本:推荐下载最新的稳定版(如 PostgreSQL 17 或 16),架构选择
Windows x86-64。
2.2 安装向导关键步骤详解
双击 .exe 文件后,请严格遵循以下设置:
- 安装目录:保持默认 (
C:\Program Files\PostgreSQL\xx)。 - 组件选择 (Select Components) ⚠️ 关键点:
- ✅ PostgreSQL Server (必选)
- ✅ pgAdmin 4 (必选,用于可视化操作)
- ✅ Command Line Tools (必选,用于命令行调试)
- ❌ Stack Builder (安装完成后弹出的额外窗口,直接关闭或选 No,无需安装)
- 设置超级用户密码 (Superuser Password) 🔑 最重要:
- 用户名默认为
postgres。 - 密码:设置一个你记得住的密码(开发环境可用
123456,生产环境必须复杂)。 - 注意:这个密码将用于
.env配置和 pgAdmin 登录。
- 用户名默认为
- 端口 (Port):保持默认
5432。 - 区域 (Locale):保持默认
Default locale。
🎉 总结
通过这张架构逻辑图和类型推导流程,我们清晰地看到了:
- 单一事实来源:
schema.ts定义了结构,也定义了类型。 - 自动化魔法:
$inferInsert自动过滤掉系统字段,让你只关心业务数据。 - 全链路安全:从配置文件的路径检查,到 TypeScript 的编译时校验,再到数据库的最终写入,每一层都有保护。
现在,你不仅拥有了一个可运行的环境,更掌握了一套类型驱动开发 (Type-Driven Development) 的最佳实践。去构建你的应用吧!🚀
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)