database-migration
3
总安装量
3
周安装量
#62676
全站排名
安装命令
npx skills add https://github.com/dseirz-rgb/worker --skill database-migration
Agent 安装分布
opencode
3
gemini-cli
3
claude-code
3
github-copilot
3
codex
3
amp
3
Skill 文档
Database Migration (æ°æ®åºè¿ç§»)
ð æ ¸å¿ç念: æ°æ®åºè¿ç§»æ¯é«é£é©æä½ï¼å¿ é¡»éµå¾ªä¸¥æ ¼çå®å ¨å·¥ä½æµãå¤ä»½ä¼å ï¼æµè¯å è¡ï¼åæ»å°±ç»ªã
ð´ 第ä¸ååï¼æ°¸è¿ä¸è¦ç´æ¥å¨ç产ç¯å¢æ§è¡æªæµè¯çè¿ç§»
â éè¯¯åæ³: ç´æ¥å¨çäº§æ°æ®åºæ§è¡ ALTER TABLE
â
æ£ç¡®åæ³: æ¬å°æµè¯ â é¢åå¸éªè¯ â ç产æ§è¡ â éªè¯åæ»
â éè¯¯åæ³: "è¿åªæ¯å ä¸ªåæ®µï¼åºè¯¥æ²¡é®é¢"
â
æ£ç¡®åæ³: ä»»ä½ schema åæ´é½è¦èµ°å®æ´æµç¨
When to Use This Skill
ä½¿ç¨æ¤æè½å½ä½ éè¦ï¼
- æ·»å /å é¤/ä¿®æ¹æ°æ®åºè¡¨æå段
- å建æä¿®æ¹ç´¢å¼
- æ§è¡æ°æ®è¿ç§»ï¼data migrationï¼
- åæ»å¤±è´¥çè¿ç§»
- å¤çç ´åæ§åæ´ï¼å é¤å段ãä¿®æ¹ç±»åï¼
- å¨ç产ç¯å¢æ§è¡ schema åæ´
Not For / Boundaries
æ¤æè½ä¸éç¨äºï¼
- 纯æ¥è¯¢ä¼åï¼ä¸æ¶å schema åæ´ï¼
- åºç¨å±ä»£ç ä¿®æ¹
- æ°æ®åºå¤ä»½æ¢å¤ï¼åèè¿ç»´ææ¡£ï¼
Quick Reference
ð¯ è¿ç§»å®å ¨å·¥ä½æµ
éæ±åæ â ç¼åè¿ç§» â æ¬å°æµè¯ â å¤ä»½ç产 â æ§è¡è¿ç§» â éªè¯ç»æ â çæ§
â â
è¯ä¼°é£é© 失败 â åæ»
ð è¿ç§»åå¿ é®æ¸ å
| é®é¢ | ç®ç |
|---|---|
| 1. è¿æ¯ç ´åæ§åæ´åï¼ | å é¤/éå½ååæ®µéè¦ç¹æ®å¤ç |
| 2. æ°æ®éæå¤å¤§ï¼ | 大表è¿ç§»éè¦åæ¹æ§è¡ |
| 3. ææ²¡æä¾èµè¿ä¸ªå段ç代ç ï¼ | ç¡®ä¿ä»£ç å å ¼å®¹ |
| 4. åæ»æ¹æ¡æ¯ä»ä¹ï¼ | å¿ é¡»æå¯æ§è¡çåæ»èæ¬ |
| 5. è¿ç§»éè¦å¤é¿æ¶é´ï¼ | è¯ä¼°æ¯å¦éè¦ç»´æ¤çªå£ |
â è¿ç§»ç±»åé£é©ç级
| æä½ç±»å | é£é©ç级 | 注æäºé¡¹ |
|---|---|---|
| æ·»å å¯ç©ºå段 | ð¢ ä½ | æå®å ¨çæä½ |
| æ·»å 带é»è®¤å¼çåæ®µ | ð¡ ä¸ | 大表å¯è½é表 |
| æ·»å ç´¢å¼ | ð¡ ä¸ | ä½¿ç¨ CONCURRENTLY |
| ä¿®æ¹å段类å | ð´ é« | å¯è½ä¸¢å¤±æ°æ® |
| å é¤å段 | ð´ é« | ä¸å¯éæä½ |
| éå½ååæ®µ | ð´ é« | éè¦ä»£ç é å |
| å é¤è¡¨ | ð´ æé« | å¿ é¡»ç¡®è®¤æ ä¾èµ |
è¿ç§»å®å ¨å·¥ä½æµè¯¦è§£
Phase 1: å¤ä»½
ç产ç¯å¢è¿ç§»åå¿ é¡»å¤ä»½ï¼
# Supabase å¤ä»½
# æ¹å¼ 1: ä½¿ç¨ Supabase Dashboard 导åº
# æ¹å¼ 2: ä½¿ç¨ pg_dump
# 导åºå®æ´æ°æ®åº
pg_dump -h <host> -U postgres -d postgres > backup_$(date +%Y%m%d_%H%M%S).sql
# åªå¯¼åº schema
pg_dump -h <host> -U postgres -d postgres --schema-only > schema_backup.sql
# åªå¯¼åºç¹å®è¡¨
pg_dump -h <host> -U postgres -d postgres -t <table_name> > table_backup.sql
Phase 2: æ¬å°æµè¯
# 1. çæè¿ç§»æä»¶
pnpm drizzle-kit generate
# 2. æ£æ¥çæç SQL
cat drizzle/<migration_file>.sql
# 3. 卿¬å°æ°æ®åºæµè¯
pnpm drizzle-kit push
# 4. éªè¯ schema æ£ç¡®
pnpm drizzle-kit studio
Phase 3: æ§è¡è¿ç§»
# ç产ç¯å¢è¿ç§»
pnpm drizzle-kit push --config=drizzle.config.prod.ts
# æä½¿ç¨è¿ç§»æä»¶
pnpm drizzle-kit migrate
Phase 4: éªè¯ç»æ
-- æ£æ¥è¡¨ç»æ
\d+ <table_name>
-- æ£æ¥æ°æ®å®æ´æ§
SELECT COUNT(*) FROM <table_name>;
-- æ£æ¥çº¦æ
SELECT * FROM information_schema.table_constraints
WHERE table_name = '<table_name>';
Drizzle ORM è¿ç§»æå
åºæ¬é ç½®
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
常ç¨å½ä»¤
# çæè¿ç§»æä»¶ï¼åºäº schema åæ´ï¼
pnpm drizzle-kit generate
# æ¨é schema å°æ°æ®åºï¼å¼åç¯å¢ï¼
pnpm drizzle-kit push
# æ§è¡è¿ç§»æä»¶ï¼ç产ç¯å¢ï¼
pnpm drizzle-kit migrate
# æ¥çæ°æ®åºç¶æ
pnpm drizzle-kit studio
# æ£æ¥ schema å·®å¼
pnpm drizzle-kit check
Schema å®ä¹ç¤ºä¾
// src/db/schema.ts
import { pgTable, text, timestamp, uuid, boolean, integer } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: text('email').notNull().unique(),
name: text('name'),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
export const posts = pgTable('posts', {
id: uuid('id').primaryKey().defaultRandom(),
title: text('title').notNull(),
content: text('content'),
authorId: uuid('author_id').references(() => users.id),
published: boolean('published').default(false),
viewCount: integer('view_count').default(0),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
ç ´åæ§åæ´å¤ç
å é¤å段çå®å ¨æµç¨
1. 代ç ä¸ç§»é¤å¯¹è¯¥åæ®µçææå¼ç¨
2. é¨ç½²ä»£ç åæ´
3. çå¾
确认æ é®é¢ï¼å»ºè®® 24-48 å°æ¶ï¼
4. æ§è¡æ°æ®åºè¿ç§»å é¤å段
éå½ååæ®µçå®å ¨æµç¨
1. æ·»å æ°å段
2. æ°æ®è¿ç§»ï¼å¤å¶æ§åæ®µæ°æ®å°æ°å段
3. ä»£ç æ¹ä¸ºä½¿ç¨æ°å段
4. é¨ç½²ä»£ç
5. 确认æ é®é¢åå 餿§å段
ä¿®æ¹å段类åçå®å ¨æµç¨
1. æ·»å æ°åæ®µï¼æ°ç±»åï¼
2. æ°æ®è¿ç§»ï¼è½¬æ¢å¹¶å¤å¶æ°æ®
3. ä»£ç æ¹ä¸ºä½¿ç¨æ°å段
4. é¨ç½²ä»£ç
5. 确认æ é®é¢åå 餿§å段
åæ»çç¥
åæ»åå
- æ¯ä¸ªè¿ç§»é½è¦æå¯¹åºçåæ»èæ¬
- åæ»èæ¬å¿ é¡»å¨æ§è¡è¿ç§»åæµè¯
- ç ´åæ§åæ´çåæ»éè¦æ°æ®æ¢å¤
åæ»æ¹å¼
æ¹å¼ 1: ä½¿ç¨ Drizzle åæ»
# Drizzle ç®å䏿¯æèªå¨åæ»ï¼éè¦æå¨ç¼å
æ¹å¼ 2: æå¨ SQL åæ»
-- åæ»æ·»å åæ®µ
ALTER TABLE users DROP COLUMN new_field;
-- åæ»æ·»å ç´¢å¼
DROP INDEX idx_users_email;
-- åæ»æ·»å 表
DROP TABLE new_table;
æ¹å¼ 3: ä»å¤ä»½æ¢å¤
# æ¢å¤å®æ´æ°æ®åº
psql -h <host> -U postgres -d postgres < backup.sql
# æ¢å¤ç¹å®è¡¨
psql -h <host> -U postgres -d postgres < table_backup.sql
ç产ç¯å¢è¿ç§»æ³¨æäºé¡¹
ð¨ é«é£é©æä½æ£æ¥æ¸ å
- å·²åå»ºæ°æ®åºå¤ä»½
- 已卿¬å°/é¢åå¸ç¯å¢æµè¯
- å·²åå¤åæ»èæ¬
- å·²éç¥ç¸å ³å¢éæå
- 已鿩ä½å³°ææ§è¡
- å·²åå¤çæ§åè¦
大表è¿ç§»çç¥
-- æ·»å ç´¢å¼æ¶ä½¿ç¨ CONCURRENTLYï¼ä¸é表ï¼
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
-- 大表添å åæ®µæ¶åæ¹æ´æ°é»è®¤å¼
-- 1. å
æ·»å å¯ç©ºå段
ALTER TABLE large_table ADD COLUMN new_field TEXT;
-- 2. åæ¹æ´æ°æ°æ®
UPDATE large_table SET new_field = 'default'
WHERE id IN (SELECT id FROM large_table WHERE new_field IS NULL LIMIT 10000);
-- 3. æåæ·»å NOT NULL 约æ
ALTER TABLE large_table ALTER COLUMN new_field SET NOT NULL;
é¶åæºè¿ç§»æ¨¡å¼
1. æ·»å æ°å段ï¼å¯ç©ºï¼
2. é¨ç½²ä»£ç ï¼åæ¶åå
¥æ°æ§å段
3. æ°æ®è¿ç§»ï¼å¡«å
å岿°æ®
4. é¨ç½²ä»£ç ï¼åªè¯»åæ°å段
5. å 餿§å段
Examples
Example 1: æ·»å æ°å段
Input: “éè¦ç» users 表添å avatar_url åæ®µ”
Steps:
- ä¿®æ¹ schema æä»¶
- çæè¿ç§»
- æ¬å°æµè¯
- ç产æ§è¡
Expected Output:
// src/db/schema.ts
export const users = pgTable('users', {
// ... ç°æåæ®µ
avatarUrl: text('avatar_url'), // æ°å¢å¯ç©ºå段
});
# çæè¿ç§»
pnpm drizzle-kit generate
# æ£æ¥çæç SQL
# ALTER TABLE users ADD COLUMN avatar_url TEXT;
# æ§è¡è¿ç§»
pnpm drizzle-kit push
Example 2: å®å ¨å é¤å段
Input: “éè¦å é¤ users 表ç legacy_field åæ®µ”
Steps:
- 确认代ç 䏿 å¼ç¨
- å¤ä»½æ°æ®
- æ§è¡å é¤
Expected Output:
# 1. æç´¢ä»£ç 确认æ å¼ç¨
grep -r "legacy_field" src/
# 2. å¤ä»½è¯¥åæ®µæ°æ®
psql -c "COPY (SELECT id, legacy_field FROM users) TO '/tmp/legacy_backup.csv' CSV HEADER;"
# 3. ä¿®æ¹ schema ç§»é¤å段
# 4. çæå¹¶æ§è¡è¿ç§»
pnpm drizzle-kit generate
pnpm drizzle-kit push
Example 3: æ·»å ç´¢å¼
Input: “users 表ç email æ¥è¯¢å¾æ ¢ï¼éè¦æ·»å 索弔
Steps:
- åææ¥è¯¢æ¨¡å¼
- å建索å¼
- éªè¯æ§è½
Expected Output:
// src/db/schema.ts
import { pgTable, text, index } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').primaryKey(),
email: text('email').notNull(),
}, (table) => ({
emailIdx: index('idx_users_email').on(table.email),
}));
-- ç产ç¯å¢ä½¿ç¨ CONCURRENTLY é¿å
é表
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
References
references/drizzle-templates.md: Drizzle ORM è¿ç§»ä»£ç 模æ¿references/rollback-strategies.md: åç±»è¿ç§»çåæ»çç¥
Maintenance
- Sources: Drizzle ORM 宿¹ææ¡£, PostgreSQL æä½³å®è·µ
- Last Updated: 2025-01-01
- Known Limits:
- åæ»çç¥ä¾èµæå¨ç¼å
- å¤§è§æ¨¡æ°æ®è¿ç§»éè¦é¢å¤å·¥å ·æ¯æ