Prisma 移动
Prisma 的基于脚本的数据迁移 。 运行数据转换, 并同时运行您的计划迁移, 并具有完整的类型安全和访问 Prisma 客户端 .
++ 在 0.0. 2 中新建 : 分布式锁接,分批处理,有条件的迁移,迁移的依赖性,还有更多!
为什么?
普里斯马的本土迁移处理出计划变化,但数据迁移往往需要:
- 运行 Java 脚本/ Type 脚本代码
- 使用 Prisma 客户端查询和转换数据
- SQL 无法处理的复杂数据转换
- 保持移徙历史和回滚能力
这个扩展提供了无缝的写出,运行,以及使用TypeScript管理数据迁移的方法.
安装
npm install prisma-shift
# or
yarn add prisma-shift
# or
pnpm add prisma-shift
Prisma 发电机(建议)
整合数据迁移的最清洁方式是使用 Prisma 生成器中添加此选项 schema.prisma数字 :
generator dataMigration {
provider = "prisma-shift-generator"
migrationsDir = "./prisma/data-migrations" // optional
}
现在数据迁移将 自动运行 prisma migrate deploy数字 :
npx prisma migrate deploy # Schema + data migrations in one command!
生成器选项
| 选项 | 说明 | 默认 |
|---|---|---|
migrationsDir | 迁移文件目录 | ./prisma/data-migrations |
migrationsTable | 移民历史数据库表 | _dataMigration |
环境变量
您也可以通过环境变量配置 :
DATA_MIGRATIONS_DIR=./prisma/data-migrations
DATA_MIGRATIONS_TABLE=_dataMigration
Prisma CLI 整合
或者,用我们的 Prisma CLI 包装器 自动运行在图中迁移后的数据迁移:
替换 prisma 与 prisma-shift-migrate
# Instead of running these 3 commands:
# npx prisma migrate deploy
# npx prisma generate
# npx prisma-shift run
# Just run this ONE command:
npx prisma-shift-migrate migrate deploy
添加到您的包裹。 json
{
"scripts": {
"migrate": "prisma-shift-migrate migrate deploy",
"migrate:dev": "prisma-shift-migrate migrate dev"
}
}
那就赶紧跑 npm run migrate - 它处理一切!
快速启动
1. 初始化
npx prisma-shift init
这创造了一个 prisma/data-migrations 目录.
2. 创造移徙
npx prisma-shift create "add_default_preferences"
生成迁移文件 :
// prisma/data-migrations/20240324120000_add_default_preferences.ts
import { DataMigration, MigrationContext } from "prisma-shift";
const migration: DataMigration = {
id: "20240324120000_add_default_preferences",
name: "add_default_preferences",
createdAt: 1711281600000,
async up({ prisma, log }: MigrationContext) {
await prisma.user.updateMany({
where: { preferences: null },
data: { preferences: { theme: "light", notifications: true } }
});
log("Added default preferences to users");
},
async down({ prisma, log }: MigrationContext) {
await prisma.user.updateMany({
data: { preferences: null }
});
log("Cleared user preferences");
}
};
export default migration;
3. 管理移徙
备选办法A:结合Prisma CLI(建议)
使用我们的空降替代 Prisma CLI :
# This runs schema migrations + data migrations together!
npx prisma-shift-migrate migrate deploy
备选案文B:手册
# Run data migrations only
npx prisma-shift run
# Run schema + data migrations together
npx prisma-shift run --with-schema
# Wait for lock if another instance is running
npx prisma-shift run --wait
++ 完整示例
见 统一民主 综合实例 3个计划迁移 财务报告和审定财务报表 12个数据迁移数字 :
cd examples/unified-demo
# Start PostgreSQL (Docker)
docker-compose up -d
# Install and run
npm install && npm run migrate
演示内容包括:
- 多克编曲 - PostgreSQL + 管理者数据库
- 3 Schema 移民(SQL) - 创建表格并添加列
- 12 数据迁移( TypeScript) - 转换数据
- JSON 数据加载 - 文件的种子数据
- 已计算字段 - 产生流涕、摘录、阅读时间
- 大型数据集处理 - 有进展的批处理
- Enum 迁移 - 变换状态值
- 多表同步 - 各表的总数
- 有条件移徙 - 基于地标的处决
- 移徙依赖性 - 确保适当订购
- 长期移徙 - 有超时支持
QQ Schema vs 数据迁移
| 类型 | 目的 | 工具 | 示例 |
|---|---|---|---|
| Schema 迁移 | 数据库结构 | prisma migrate | 添加列, 创建表格 |
| 数据迁移 | 转换数据 | prisma-shift | 回填, 常态 |
黄金规则
在依赖它们的数据迁移之前, 总是应用策略迁移 .
# 1. Schema migration (structure)
npx prisma migrate dev --name add_slug_column
# 2. Generate Prisma Client (CRITICAL!)
npx prisma generate
# 3. Data migration (transformation)
npx prisma-shift create backfill_slugs
npx prisma-shift run
用作 Prisma 扩展
备选案文1:使用 withDataMigrations
import { PrismaClient } from "@prisma/client";
import { withDataMigrations } from "prisma-shift";
const basePrisma = new PrismaClient();
const prisma = withDataMigrations(basePrisma, {
migrationsDir: "./prisma/data-migrations",
});
// Now available:
// await prisma.$dataMigrations.run() // Run pending
// await prisma.$dataMigrations.status() // Check status
// await prisma.$dataMigrations.rollback() // Rollback last
备选案文2:使用 createPrismaClientWithMigrations
import { createPrismaClientWithMigrations } from "prisma-shift";
const prisma = createPrismaClientWithMigrations({
migrationsDir: "./prisma/data-migrations",
autoRun: true, // Auto-run on startup (optional)
});
CLI 命令
| 命令 | 说明 |
|---|---|
prisma-shift-migrate | 滴入式 CLI 替换 ⭐ |
deploy | 一起运行 schema + 数据迁移 |
init | 初始化数据迁移 |
create <name> | 创建新数据迁移 |
status | 显示迁移状态 |
run | 只运行数据迁移 |
run --with-schema | 运行 schema + 数据迁移 |
run --wait | 如果另一个实例正在运行, 请等待锁定 |
run --dry-run | 预览将运行的 |
validate | 验证迁移文件 |
rollback | 上次回滚迁移 |
reset | 清除移徙记录 |
squash | 将多个移入 |
export | 出口移民历史 |
Prisma CLI 剪贴机( 建议)
使用 prisma-shift-migrate 和普通的Prisma CLI一样:
# Deploy schema + data migrations in one command
npx prisma-shift-migrate migrate deploy
# Development mode
npx prisma-shift-migrate migrate dev
# Generate client
npx prisma-shift-migrate generate
添加到您的 package.json数字 :
{
"scripts": {
"migrate": "prisma-shift-migrate migrate deploy",
"migrate:dev": "prisma-shift-migrate migrate dev"
}
}
平地移徙
通过将多种移徙合并为一种来清理长期移徙历史:
# Squash migrations from March 2024 into a single file
npx prisma-shift squash --from=20240301 --to=20240331 --name="march_changes"
# Dry run to preview what would happen
npx prisma-shift squash --from=20240301 --to=20240331 --name="march_changes" --dry-run
# Keep original files (don't delete them)
npx prisma-shift squash --from=20240301 --to=20240331 --name="march_changes" --keep
它会做什么:
- 合并所有迁移
up区域中的函数输入一个新的迁移文件 - 删除原始迁移文件( 除非
--keep用于) - 更新数据库迁移记录,以反映被压抑的迁移
- 只有工作在 已执行 迁移(待迁移范围将阻碍行动)
统一部署指挥部(建议)
运行 所有的东西 在一个命令中:
npx prisma-shift deploy
运行完整序列 :
prisma migrate deploy- Schema移民prisma generate- 生成 Prisma 客户端prisma-shift run- 数据迁移
部署脚本
备选方案1:使用统一部署指挥
#!/bin/bash
set -e
# One command does it all!
npx prisma-shift deploy
npm start
备选案文2:手动序列(如果需要更多的控制)
#!/bin/bash
set -e
npx prisma migrate deploy # Schema migrations
npx prisma generate # Generate client
npx prisma-shift run # Data migrations
npm start
备选办法3:使用等待旗(用于多层部署)
#!/bin/bash
set -e
# Use --wait to ensure only one instance runs migrations at a time
npx prisma-shift run --with-schema --wait
npm start
高级特性
有条件移徙
仅在满足条件时进行迁移 :
const migration: DataMigration = {
id: "20240325120000_enable_feature_x",
name: "enable_feature_x",
// Only run if condition is met
condition: async ({ prisma }) => {
const config = await prisma.config.findFirst();
return config?.featureXEnabled === true;
},
async up({ prisma, log }) {
// Migration logic
log("Feature X is enabled, running migration...");
},
};
移徙依赖性
确保按正确顺序迁移:
const migration: DataMigration = {
id: "20240325_add_user_stats",
name: "add_user_stats",
// Requires these schema migrations first
requiresSchema: ["20240324000002_add_categories"],
// And these data migrations
requiresData: ["20240324010003_setup_profiles"],
async up({ prisma, log }) {
// Migration logic
},
};
批处理
高效处理大型数据集:
async up({ prisma, log, batch }: MigrationContext) {
await batch({
query: () => prisma.post.findMany({ where: { processed: false } }),
batchSize: 1000,
process: async (posts) => {
await prisma.post.updateMany({
where: { id: { in: posts.map(p => p.id) } },
data: { processed: true }
});
},
onProgress: (processed, total) => {
log(`Processed ${processed}/${total}`);
},
});
}
长跑移徙
超过交易超时的迁移:
const migration: DataMigration = {
id: "20240325_backfill_large_table",
name: "backfill_large_table",
// Custom timeout (default: 0 = no timeout)
timeout: 300000, // 5 minutes
// Disable transaction for very long operations
disableTransaction: true,
async up({ prisma, log, signal }) {
// Check for cancellation
if (signal?.aborted) {
throw new Error("Migration was cancelled");
}
// Long-running work...
},
};
分布式锁定
防止在多重部署中同时迁移:
const runner = new MigrationRunner(prisma, {
migrationsDir: "./migrations",
lock: {
enabled: true,
timeout: 30000, // Lock expires after 30s
retryAttempts: 3, // Retry 3 times
retryDelay: 1000, // Wait 1s between retries
},
});
或者用那个 --wait CLI旗无限期等:
npx prisma-shift run --wait
钩子
迁移前后运行脚本 :
// prisma-shift.config.ts
export default {
hooks: {
beforeAll: "./scripts/backup.ts", // Before any migration
beforeEach: "./scripts/notify.ts", // Before each migration
afterEach: "./scripts/verify.ts", // After each migration
afterAll: "./scripts/cleanup.ts", // After all migrations
},
};
常见模式
正在装入 JSON 数据
import * as fs from "fs";
const data = JSON.parse(fs.readFileSync("./data/seed.json", "utf8"));
for (const item of data) {
await prisma.user.create({ data: item });
}
《同上》更新
// Only process unmigrated records
const posts = await prisma.post.findMany({
where: { slug: null },
});
Batching 大型数据集
const BATCH_SIZE = 1000;
while (hasMore) {
const batch = await prisma.post.findMany({
where: { processed: false },
take: BATCH_SIZE,
});
// Process batch...
}
配置
创建一个 prisma-shift.config.ts 文件 :
export default {
migrationsDir: "./prisma/data-migrations",
migrationsTable: "_dataMigration",
schemaPath: "./prisma/schema.prisma",
logging: {
level: "info", // silent, error, warn, info, debug
progress: true, // Show progress bars
format: "text", // text or json
},
lock: {
enabled: true,
timeout: 30000,
retryAttempts: 3,
retryDelay: 1000,
},
execution: {
timeout: 0, // 0 = no timeout
transaction: true, // Run in transaction by default
},
typescript: {
compiler: "tsx", // tsx or ts-node
transpileOnly: true,
},
};
环境变量
DATA_MIGRATIONS_DIR=./prisma/data-migrations
DATA_MIGRATIONS_TABLE=_dataMigration
API 参考
数据迁移接口
interface DataMigration {
id: string; // Unique identifier
name: string; // Description
createdAt: number; // Timestamp
up: (context: MigrationContext) => Promise<void>;
down?: (context: MigrationContext) => Promise<void>;
condition?: (context: Pick<MigrationContext, "prisma" | "log">) => Promise<boolean>;
requiresSchema?: string[]; // Schema migration dependencies
requiresData?: string[]; // Data migration dependencies
timeout?: number; // Custom timeout in ms (0 = none)
disableTransaction?: boolean; // Run outside transaction
}
迁移内容
interface MigrationContext {
prisma: PrismaClient;
log: CallableLogger; // log("msg") or log.info("msg")
batch: <T>(options: BatchOptions<T>) => Promise<BatchResult<T>>;
progress: (total: number) => ProgressTracker;
signal?: AbortSignal; // For cancellation/timeouts
}
可调用
伐木机可用作函数或方法:
// Both work:
log("Simple message"); // Defaults to info level
log.info("Info message"); // Explicit info level
log.warn("Warning message"); // Warning level
log.error("Error message"); // Error level
log.debug("Debug message"); // Debug level
测试
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch
文档
发布注释
v0.0.2 (2026-03-28) (中文(简体) )
新特性 :
- 分配锁定 - 防止与PostgreSQL咨询锁在多个情况下同时迁移
- 移民超时 - 设定每次迁移的自定义超时,通过中止自动取消
- 在钩子之前/之后 - 在各种迁移生命周期阶段运行脚本(All、All、Arefore、Arefore、Arefore)
- XQ 批处理助手 - 通过自动标记和进度跟踪,高效地处理大型数据集
- 有条件移徙 - 仅在满足特定条件(例如地物旗)时进行迁移
- * 移徙依赖性 - 宣布依赖其他迁移,以确保正确的执行命令
- * 结构化记录 - 有多个级别、进度指标和JSON格式支持的丰富的记录
- * 进展跟踪 - 长期运行的视觉进度栏
- 移民验证 - 执行前验证迁移文件(检查ID、复制、类型脚本汇编)
- 导出功能 - 将迁移历史导出为 JSON、 CSV 或 HTML 格式
- 等待旗帜( V)
--wait(中文(简体) ) - 等待锁定购置,而不是立即失败(对多层部署来说是好事) - 使用- schema 旗帜( A)
--with-schema(中文(简体) ) - 在数据迁移之前在一个命令中运行 Prisma 计划迁移 - QQ 配置文件支持 - 通过
prisma-shift.config.ts文件
改进:
- 可调用 Logger API - 说吧
log()可调用为函数( e)log("msg")或采用方法(log.info("msg")(中文(简体) ) - 交易控制 - 为长期迁移而禁用交易的选项
- 更好的错误处理 - 清除有迁移背景的错误信息
示例使用法:
# Run with schema migrations
npx prisma-shift run --with-schema
# Wait for lock (for multi-instance deployments)
npx prisma-shift run --wait
# Preview changes
npx prisma-shift run --dry-run
# Validate migrations
npx prisma-shift validate
# Export history
npx prisma-shift export --format=json
v0.0.1 (2024-03-24) (中文(简体) )
初释:
- 基于脚本的数据迁移
- CLI 命令( init, 创建, 运行, 状态, 回滚, 重置)
- Prisma 客户端扩展名( R)
withDataMigrations(中文(简体) ) - 计划迁移后自动运行的发电机集成
- 数据库中的移徙跟踪
- 回滚支持
许可证
麻省理工学院