Drizzle 迁移基础知识

SQL 数据库要求你指定要预先存储的实体的严格模式,以及是否(何时)需要更改这些实体的形状。 - 你需要通过模式迁移来完成此操作。

有多种生产级方法来管理数据库迁移。Drizzle 的设计使其完美适配所有场景,无论你是先数据库还是先代码库。

当你的数据库模式是真实来源时,数据库优先。你可以直接在数据库上管理数据库模式,也可以通过数据库迁移工具管理,然后将数据库模式拉取到代码库应用级实体中。

代码库优先是指代码库中的数据库模式作为事实来源并受版本控制。你可以使用 JavaScript/TypeScript 声明和管理数据库模式,然后使用 Drizzle 直接或通过外部迁移工具将该模式应用于数据库本身。

Drizzle 如何提供帮助?

我们已经构建了 drizzle-kit - 用于使用 Drizzle 管理迁移的 CLI 应用。

drizzle-kit migrate
drizzle-kit generate
drizzle-kit push
drizzle-kit pull

它旨在让你根据当前的业务需求选择如何处理迁移。

它适用于数据库优先和代码库优先的方法,它允许你推送架构、生成 SQL 迁移文件或从数据库中提取架构。无论你是单独工作还是团队协作,它都是完美的选择。



现在让我们为你的项目选择最佳方案:

Option 1

我使用外部迁移工具或直接在数据库上运行 SQL 迁移来自行管理数据库模式。从 Drizzle 中,我只需要从数据库获取模式的当前状态并将其保存为 TypeScript 模式文件。

Expand details

这是一种数据库优先的方法。你拥有数据库模式作为事实来源,Drizzle 允许你使用 drizzle-kit pull 命令将数据库模式拉取到 TypeScript。

                                  ┌────────────────────────┐      ┌─────────────────────────┐ 
                                  │                        │ <---  CREATE TABLE "users" (
┌──────────────────────────┐      │                        │        "id" SERIAL PRIMARY KEY,
│ ~ drizzle-kit pull       │      │                        │        "name" TEXT,
└─┬────────────────────────┘      │        DATABASE        │        "email" TEXT UNIQUE
  │                               │                        │       );
  └ Pull datatabase schema -----> │                        │
  ┌ Generate Drizzle       <----- │                        │
  │ schema TypeScript file        └────────────────────────┘

  v
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(), 
};
Option 2

我希望我的 TypeScript 代码库中拥有数据库模式,我不想处理 SQL 迁移文件。我希望 Drizzle 能够将我的模式直接 “push” 到数据库中

Expand details

这是一种代码库优先的方法。你拥有 TypeScript Drizzle 模式作为事实来源,Drizzle 允许你使用 drizzle-kit push 命令将模式更改推送到数据库。

这是快速原型设计的最佳方法,我们已经看到数十个团队和个人开发者成功地将其用作其生产应用中的主要迁移流程。

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(), // <--- added column
};
Add column to `users` table                                                                          
┌──────────────────────────┐                  
│ + email: text().unique() │                  
└─┬────────────────────────┘                  

  v                                           
┌──────────────────────────┐                  
│ ~ drizzle-kit push       │                  
└─┬────────────────────────┘                  
  │                                           ┌──────────────────────────┐
  └ Pull current datatabase schema ---------> │                          │
                                              │                          │
  ┌ Generate alternations based on diff <---- │         DATABASE         │
  │                                           │                          │
  └ Apply migrations to the database -------> │                          │
                                       │      └──────────────────────────┘

  ┌────────────────────────────────────┴──────────────┐
   ALTER TABLE `users` ADD COLUMN `email` TEXT UNIQUE; 
Option 3

我希望我的 TypeScript 代码库中包含数据库模式,我希望 Drizzle 为我生成 SQL 迁移文件并将其应用到我的数据库。

Expand details

这是一种代码库优先的方法。你拥有 TypeScript Drizzle 模式作为事实来源,Drizzle 允许你使用 drizzle-kit generate 根据模式更改生成 SQL 迁移文件,然后使用 drizzle-kit migrate 命令将其应用到数据库。

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 schema
    3. prompt developer for renames if necessary
  ┌ 4. generate SQL migration and persist to file
  │    ┌─┴───────────────────────────────────────┐  
  │      📂 drizzle       
  │      └ 📂 20242409125510_premium_mister_fear
  │        ├ 📜 snapshot.json
  │        └ 📜 migration.sql
  v
-- drizzle/20242409125510_premium_mister_fear/migration.sql

CREATE TABLE "users" (
 "id" SERIAL PRIMARY KEY,
 "name" TEXT,
 "email" TEXT UNIQUE
);
┌───────────────────────┐                  
│ $ drizzle-kit migrate │                  
└─┬─────────────────────┘                  
  │                                                         ┌──────────────────────────┐                                         
  └ 1. read migration.sql files in migrations folder        │                          │
    2. fetch migration history from database -------------> │                          │
  ┌ 3. pick previously unapplied migrations <-------------- │         DATABASE         │
  └ 4. apply new migration to the database ---------------> │                          │
                                                            │                          │
                                                            └──────────────────────────┘
[✓] done!                                                 
Option 4

我希望我的 TypeScript 代码库中包含数据库模式,我希望 Drizzle 为我生成 SQL 迁移文件,并且我希望 Drizzle 在运行时应用它们。

Expand details

这是一种代码库优先的方法。你拥有 TypeScript Drizzle 模式作为事实来源,Drizzle 允许你使用 drizzle-kit generate 根据模式更改生成 SQL 迁移文件,然后你可以在应用运行时将它们应用到数据库。

这种方法广泛用于单体应用,当你在零停机部署期间应用数据库迁移,并在出现故障时回滚 DDL 更改时。这也适用于无服务器部署,在部署过程中,迁移会在自定义资源中运行一次。

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 schema
    3. prompt developer for renames if necessary
  ┌ 4. generate SQL migration and persist to file
  │    ┌─┴───────────────────────────────────────┐  
  │      📂 drizzle       
  │      └ 📂 20242409125510_premium_mister_fear
  │        ├ 📜 snapshot.json
  │        └ 📜 migration.sql
  v
-- drizzle/20242409125510_premium_mister_fear/migration.sql

CREATE TABLE "users" (
 "id" SERIAL PRIMARY KEY,
 "name" TEXT,
 "email" TEXT UNIQUE
);
// index.ts
import { drizzle } from "drizzle-orm/node-postgres"
import { migrate } from 'drizzle-orm/node-postgres/migrator';

const db = drizzle(process.env.DATABASE_URL);

await migrate(db);
┌───────────────────────┐                  
│ npx tsx src/index.ts  │                  
└─┬─────────────────────┘                  

  ├ 1. init database connection                             ┌──────────────────────────┐                                         
  └ 2. read migration.sql files in migrations folder        │                          │
    3. fetch migration history from database -------------> │                          │
  ┌ 4. pick previously unapplied migrations <-------------- │         DATABASE         │
  └ 5. apply new migration to the database ---------------> │                          │
                                                            │                          │
                                                            └──────────────────────────┘
[✓] done!                                                 
Option 5

我希望我的 TypeScript 代码库中包含数据库模式,我希望 Drizzle 为我生成 SQL 迁移文件,但我将自行或通过外部迁移工具将它们应用到我的数据库。

Expand details

这是一种代码库优先的方法。你拥有 TypeScript Drizzle 模式作为事实来源,Drizzle 允许你使用 drizzle-kit generate 根据模式更改生成 SQL 迁移文件,然后你可以直接或通过外部迁移工具将它们应用到数据库。

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       
  │      └ 📂 20242409125510_premium_mister_fear
  │        ├ 📜 snapshot.json
  │        └ 📜 migration.sql
  v
-- drizzle/20242409125510_premium_mister_fear/migration.sql

CREATE TABLE "users" (
 "id" SERIAL PRIMARY KEY,
 "name" TEXT,
 "email" TEXT UNIQUE
);
┌───────────────────────────────────┐                  
│ (._.) now you run your migrations │           
└─┬─────────────────────────────────┘  

 directly to the database
  │                                         ┌────────────────────┐
  ├────────────────────────────────────┬───>│                    │  
  │                                    │    │      Database      │           
 or via external tools                 │    │                    │   
  │                                    │    └────────────────────┘
  │  ┌────────────────────┐            │      
  └──│ Bytebase           ├────────────┘         
     ├────────────────────┤  
     │ Liquibase          │
     ├────────────────────┤ 
     │ Atlas              │
     ├────────────────────┤ 
     │ etc…               │
     └────────────────────┘

[✓] done!                                                 
Option 6

我希望我的 TypeScript 代码库中包含数据库模式,我希望 Drizzle 将我的 Drizzle 模式的 SQL 表示输出到控制台,然后我将通过 Atlas 将它们应用到我的数据库。

Expand details

这是一种代码库优先的方法。你有 TypeScript Drizzle 架构作为可信来源,Drizzle 允许你根据 drizzle-kit export 对架构的更改导出 SQL 语句,然后你可以通过 Atlas 或其他外部 SQL 迁移工具将它们应用到数据库。

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 export   │                  
└─┬──────────────────────┘                  

  └ 1. read your drizzle schema
    2. generated SQL representation of your schema
  ┌ 3. outputs to console


  v
CREATE TABLE "users" (
 "id" SERIAL PRIMARY KEY,
 "name" TEXT,
 "email" TEXT UNIQUE
);
┌───────────────────────────────────┐                  
│ (._.) now you run your migrations │           
└─┬─────────────────────────────────┘  

 via Atlas
  │                                    ┌──────────────┐
  │  ┌────────────────────┐            │              │
  └──│ Atlas              ├───────────>│  Database    │      
     └────────────────────┘            │              │       
                                       └──────────────┘

[✓] done!