3.1 drizzle-kit 做什么
drizzle-kit 是独立的 dev 依赖——对比你的 schema 和数据库当前状态,生成 SQL diff。四个核心命令:
- generate
- 根据 schema 变化生成一份 SQL 迁移文件到
drizzle/目录(不真正改数据库)。提交到 git 作为历史。 - migrate
- 把尚未应用的迁移文件按顺序应用到数据库。生产环境用这个。
- push
- 不生成迁移文件,直接把 schema 推到数据库。仅推荐开发原型期——快但不可回溯。
- studio
- 启动本地 GUI,浏览器打开查看/编辑数据。
3.2 drizzle.config.ts
drizzle-kit 的配置文件,放项目根:
import { defineConfig } from "drizzle-kit";
export default defineConfig({
dialect: "postgresql", // "postgresql" | "mysql" | "sqlite" | "turso"
schema: "./src/schema.ts", // 或 "./src/schema/**/*.ts"
out: "./drizzle", // 迁移文件输出目录
dbCredentials: {
url: process.env.DATABASE_URL!,
},
verbose: true,
strict: true, // 破坏性变更前确认
});
3.3 基本工作流
步骤 1:改 schema.ts
export const users = pgTable("users", {
id: serial().primaryKey(),
name: text().notNull(),
+ email: text().notNull().unique(), // 新增
});
步骤 2:生成迁移
$ npx drizzle-kit generate
# 产出 drizzle/0001_add_email.sql:
ALTER TABLE "users" ADD COLUMN "email" text NOT NULL;
ALTER TABLE "users" ADD CONSTRAINT "users_email_unique" UNIQUE("email");
同时生成元数据 meta/0001_snapshot.json——下次 diff 的参照。
步骤 3:应用迁移
方式 A:用 drizzle-kit CLI(适合 dev)
$ npx drizzle-kit migrate
方式 B:在应用代码里(推荐,适合 CI/生产)
// src/migrate.ts
import { migrate } from "drizzle-orm/postgres-js/migrator";
import { db } from "./db";
await migrate(db, { migrationsFolder: "./drizzle" });
console.log("migrated");
部署启动脚本先跑这个——保证生产库 schema 永远与代码一致。
3.4 破坏性变更:列重命名
drizzle-kit 无法自动判断"把列 name 改成 full_name"是重命名还是删 name 加 full_name。它会交互式问你:
$ npx drizzle-kit generate
# ℹ column renamed from 'name' to 'full_name'?
# 1) + full_name (create column)
# 2) ~ name → full_name (rename)
# (use arrow keys)
选 rename,生成的 SQL 就是 ALTER TABLE ... RENAME COLUMN——保留数据。
3.5 push 模式:原型阶段神器
早期原型 schema 一天改 20 次,每次都生成迁移文件太繁琐:
$ npx drizzle-kit push
直接把当前 schema diff 推到数据库,不产 sql 文件。适合:
- 开发数据库(可丢失)
- 单人原型项目
- 上线前第一次"ship"前的收敛
没有迁移文件 = 不可审计、不可回滚、无法多实例协同。团队项目一定用 generate + migrate 两步流程。
3.6 introspect:从现有数据库反向生成 schema
接手老项目、库里已有表——不想手写 schema?
$ npx drizzle-kit pull
# 扫描 dbCredentials.url 指向的库,在 out 目录生成:
# schema.ts ← 完整 schema 定义
# relations.ts ← 关系定义
# 0000_initial.sql ← 同步的迁移
3.7 Drizzle Studio
$ npx drizzle-kit studio
# Drizzle Studio is up and running on https://local.drizzle.studio
本地 GUI 功能:浏览所有表、过滤/排序、原地改字段、执行自定义 SQL、看查询计划。数据和连接都在本机——不上传到任何云。
3.8 多 schema 文件
大项目表多、分模块:
src/schema/
├── users.ts
├── posts.ts
├── comments.ts
└── index.ts // export * from 每一份
// drizzle.config.ts
schema: "./src/schema/**/*.ts",
3.9 多环境配置
export default defineConfig({
dialect: "postgresql",
schema: "./src/schema/*",
out: "./drizzle",
dbCredentials: { url: process.env.DATABASE_URL! },
// 迁移时跳过某些表
schemaFilter: ["public"], // Postgres schema 过滤
tablesFilter: ["app_*"], // 只管前缀表
// 多方言场景:生成两套迁移
migrations: { prefix: "timestamp" }, // 或 "index"
});
3.10 CI 最佳实践
# .github/workflows/ci.yml 片段
- name: Check migration drift
run: npx drizzle-kit check # 确认没有漏 generate 的 schema 改动
- name: Apply migrations
run: bun run src/migrate.ts
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
drizzle-kit check 核对:"当前 schema.ts 生成的 diff,是否已经都进了 drizzle/ 目录?"——没进就 CI 失败,避免合并漏迁移。
3.11 回滚与数据修复
Drizzle 不自动生成 down 迁移(如 Rails 那种 up/down)。实践上:
- 每次迁移写成可前进的幂等 SQL——不写"反向"。
- 真要回滚:手写一个新的"修复迁移",不改历史。
- 重要迁移在 staging 先跑,备份数据库后再上生产。
3.12 小结
- drizzle.config.ts 声明方言、schema 路径、输出目录、连接串。
- 开发:原型期用
push,收敛后切generate + migrate。 - CI 用
drizzle-kit check防止漏迁移;生产启动前跑migrate。 - 接手老库用
pull反向生成 schema。 drizzle-kit studio是免费的本地 GUI。