drizzle-kit generate

本指南假定您熟悉

`drizzle-kit generate` 允许您根据 Drizzle schema 的声明或后续 schema 更改生成 SQL 迁移。

底层原理是什么?

Drizzle Kit `generate` 命令会触发一系列事件:

  1. 它会读取您的 Drizzle schema 文件,并生成 schema 的 JSON 快照。
  2. 它会读取您之前的迁移文件夹,并将当前 JSON 快照与最新快照进行比较。
  3. 根据 JSON 差异,它将生成 SQL 迁移。
  4. 将 `migration.sql` 和 `snapshot.json` 保存在迁移文件夹中,以当前时间戳命名。
src/schema.ts
import * as p from "./drizzle-orm/pg-core";

export const users = p.pgTable("users", {
  id: p.serial().primaryKey(),
  name: p.text(),
  email: p.text().unique(), 
};
┌────────────────────────┐                  
│ $ drizzle-kit generate │                  
└─┬──────────────────────┘                  

  └ 1. read previous migration folders
    2. find diff between current and previous scheama
    3. prompt developer for renames if necessary
  ┌ 4. generate SQL migration and persist to file
  │    ┌─┴───────────────────────────────────────┐  
  │      📂 drizzle       
  │      ├ 📂 _meta
  │      └ 📜 0000_premium_mister_fear.sql
  v
-- drizzle/0000_premium_mister_fear.sql

CREATE TABLE "users" (
 "id" SERIAL PRIMARY KEY,
 "name" TEXT,
 "email" TEXT UNIQUE
);

它旨在覆盖管理 Drizzle 迁移的代码优先方法。您可以使用`drizzle-kit migrate`、drizzle-orm 的 `migrate()`、外部迁移工具(如 bytebase)或直接在数据库上运行迁移来应用生成的迁移。

`drizzle-kit generate` 命令要求您提供 `dialect` 和 `schema` 路径选项,您可以通过 drizzle.config.ts 配置文件或 CLI 选项进行设置。

使用配置文件
作为 CLI 选项
// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  schema: "./src/schema.ts",
});
npx drizzle-kit generate

模式文件路径

您可以有一个 `schema.ts` 文件,也可以有任意数量的 schema 文件分散在项目中。Drizzle Kit 要求您通过 `schema` 配置选项以 glob 模式指定它们的路径。

示例 1
示例 2
示例 3
示例 4
📦 <project root>
 ├ ...
 ├ 📂 drizzle
 ├ 📂 src
 │ ├ ...
 │ ├ 📜 index.ts
 │ └ 📜 schema.ts 
 ├ 📜 drizzle.config.ts
 └ 📜 package.json
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./src/schema.ts",
});

自定义迁移文件名

您可以通过提供 `--name` CLI 选项来设置自定义迁移文件名。

npx drizzle-kit generate --name=init
📦 <project root>
 ├ 📂 drizzle
 │ ├ 📂 _meta
 │ └ 📜 0000_init.sql 
 ├ 📂 src
 └ …

单个项目中的多个配置文件

您可以在项目中拥有多个配置文件,这在您有多个数据库阶段、多个数据库或同一项目中有不同的数据库时非常有用。

npm
yarn
pnpm
bun
npx drizzle-kit generate --config=drizzle-dev.config.ts
npx drizzle-kit generate --config=drizzle-prod.config.ts
📦 <project root>
 ├ 📂 drizzle
 ├ 📂 src
 ├ 📜 .env
 ├ 📜 drizzle-dev.config.ts
 ├ 📜 drizzle-prod.config.ts
 ├ 📜 package.json
 └ 📜 tsconfig.json

自定义迁移

您可以生成空的迁移文件,用于编写 Drizzle Kit 当前不支持的 DDL 更改或数据填充的自定义 SQL 迁移。有关自定义迁移的详细文档,请参阅此处

drizzle-kit generate --custom --name=seed-users
📦 <project root>
 ├ 📂 drizzle
 │ ├ 📂 _meta
 │ ├ 📜 0000_init.sql 
 │ └ 📜 0001_seed-users.sql 
 ├ 📂 src
 └ …
-- ./drizzle/0001_seed-users.sql

INSERT INTO "users" ("name") VALUES('Dan');
INSERT INTO "users" ("name") VALUES('Andrew');
INSERT INTO "users" ("name") VALUES('Dandrew');

可用配置的扩展列表

`drizzle-kit generate` 包含一些仅限 CLI 的选项:

custom生成用于自定义迁移的空 SQL
name生成具有自定义名称的迁移
npm
yarn
pnpm
bun
npx drizzle-kit generate --name=init
npx drizzle-kit generate --name=seed_users --custom



我们建议通过 drizzle.config.ts 文件配置 drizzle-kit,但在必要时,您也可以通过 CLI 提供所有配置选项,例如在 CI/CD 流水线中。

dialect必填数据库方言,可以是 postgresql mysql sqlite turso singlestore 之一
schema必填TypeScript 模式文件或包含多个模式文件的文件夹路径
out迁移输出文件夹,默认为 `./drizzle`
config配置文件路径,默认为 `drizzle.config.ts`
breakpointsSQL 语句断点,默认为 `true`

扩展示例

一个示例,展示如何创建一个名为 `0001_seed-users.sql` 的自定义 postgresql 迁移文件,其中 Drizzle schema 位于 `./src/schema.ts`,迁移文件夹名为 `./migrations` 而非默认的 `./drizzle`。

我们还将 drizzle 配置文件放在 `configs` 文件夹中。

我们来创建配置文件

📦 <project root>
 ├ 📂 migrations
 ├ 📂 configs
 │ └ 📜 drizzle.config.ts
 ├ 📂 src
 └ …
drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  schema: "./src/schema.ts",
  out: "./migrations",
});

现在运行

npx drizzle-kit generate --config=./configs/drizzle.config.ts --name=seed-users --custom

然后它将成功生成

📦 <project root>
 ├ …
 ├ 📂 migrations
 │ ├ 📂 _meta
 │ ├ 📜 0000_init.sql 
 │ └ 📜 0001_seed-users.sql 
 └ …
-- ./drizzle/0001_seed-users.sql

INSERT INTO "users" ("name") VALUES('Dan');
INSERT INTO "users" ("name") VALUES('Andrew');
INSERT INTO "users" ("name") VALUES('Dandrew');