You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Drizzle ORM实现类似Django的自定义数据迁移?

Drizzle 实现自定义数据迁移的方法

Drizzle 虽然默认的drizzle-kit generate:pg只检测架构变更,但完全可以通过手动创建迁移文件的方式实现类似Django的自定义数据迁移,确保操作仅执行一次。以下是具体方案:

方案一:手动创建独立数据迁移文件

Drizzle 依赖__drizzle_migrations表跟踪已执行的迁移,每个迁移文件有唯一的时间戳前缀和哈希,只要遵循命名规则,就能实现单次执行:

  • 找到你的Drizzle迁移目录(默认是./drizzle)
  • 新建迁移文件,命名格式与自动生成的一致:YYYYMMDDHHMMSS_描述.ts(例如20240520143000_add_initial_admin_user.ts)
  • 文件中导出up(执行迁移)和down(回滚迁移)函数,使用Drizzle ORM API或原生SQL完成数据操作

示例代码:

import { sql } from "drizzle-orm";
import { pgTable, varchar, timestamp } from "drizzle-orm/pg-core";

// 假设你的用户表定义
const users = pgTable("users", {
  id: varchar("id").primaryKey(),
  name: varchar("name").notNull(),
  createdAt: timestamp("created_at").defaultNow(),
});

export async function up(db: any) {
  // 插入初始数据,支持ORM方法或原生SQL
  await db.insert(users).values([
    { id: "admin_001", name: "系统管理员" },
  ]);

  // 也可以用原生SQL实现更复杂的逻辑
  // await db.execute(sql`
  //   INSERT INTO users (id, name)
  //   VALUES ('admin_001', '系统管理员')
  //   ON CONFLICT (id) DO NOTHING;
  // `);
}

export async function down(db: any) {
  // 回滚操作:删除插入的测试数据
  await db.delete(users).where(sql`id = 'admin_001'`);
}

创建完成后,执行drizzle-kit push:pg或通过Drizzle ORM的migrate方法运行迁移,该文件会被执行一次并记录到迁移表中,不会重复执行。

方案二:在架构迁移中嵌入数据操作

如果需要和架构变更同步执行数据操作,可以在自动生成的架构迁移文件的up函数末尾添加带条件判断的数据操作,避免重复执行:

export async function up(db: any) {
  // 自动生成的架构变更代码(例如创建users表)
  await db.execute(sql`CREATE TABLE users (...)`);

  // 条件插入数据,确保仅执行一次
  await db.execute(sql`
    INSERT INTO users (id, name)
    SELECT 'admin_001', '系统管理员'
    WHERE NOT EXISTS (SELECT 1 FROM users WHERE id = 'admin_001');
  `);
}

这种方式适合和架构强关联的数据初始化,但建议优先使用方案一,保持架构变更与数据迁移的分离,便于维护。

注意事项

  • 手动迁移文件的时间戳前缀必须大于已有的迁移文件,保证执行顺序正确
  • 不要修改已执行过的迁移文件,否则会导致哈希校验失败,Drizzle会将其视为新迁移
  • down函数需实现反向操作,方便后续回滚测试

内容的提问来源于stack exchange,提问作者Janne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 04:15:19