💻

database-migration

👤 ҉Breeze🌔 📦 v1.0.0 ⭐ 4.4 ⬇️ 172 下載
💻 開發程式設計 免費

📖 技能介紹


name: database-migration slug: "database-migration" version: "1.0.0" displayName: "database-migration" summary: "使用 Alembic、Prisma Migrate、Flyway 和 Knex 等工具建立、執行和回滾版本化資料庫模式遷移。" description: 使用 Alembic、Prisma Migrate、Flyway 和 Knex 等工具建立、執行和回滾版本化資料庫模式遷移。 license: MIT metadata: author: AI Agent Skills Community version: 1.0.0

小蔥技能站7w4.net發現了升級外掛。


Database Migration

該技能使 AI agent 能夠通過遷移框架管理版本化的資料庫模式變更。agent 建立向前和向後遷移指令碼,處理模式變更期間的資料填充,確保使用安全的遷移模式實現零停機部署,並將遷移工作流整合到 CI/CD 流水線中。它支援的主要工具包括 Alembic(Python/SQLAlchemy)、Prisma Migrate(TypeScript/Node)、Flyway(Java/SQL)和 Knex(JavaScript)。

Workflow

  1. 評估模式變更: 分析請求的變更——新增列、建立表、修改約束、重新命名欄位或轉換資料。將變更分類為向後相容(新增)或破壞性(刪除),以確定部署策略。破壞性變更需要採用多階段遷移方法。

  2. 選擇遷移工具: 根據專案的技術棧選擇合適的遷移框架。對於 Python/SQLAlchemy 專案使用 Alembic,對於 TypeScript/Prisma 專案使用 Prisma Migrate,對於 Java 或 SQL-first 工作流使用 Flyway,對於 Node.js/Express 專案使用 Knex。確保該工具已初始化並連線到目標資料庫。

  3. 生成遷移指令碼: 在支援的場景下自動生成遷移指令碼(Alembic autogenerate、Prisma migrate dev),然後審查並編輯生成的指令碼。新增顯式的回滾(降級)邏輯。對於資料填充,將資料轉換包含在遷移中以保持模式和資料變更的一致性。

  4. 在預發環境中測試: 在映象生產環境的預發資料庫上應用遷移。驗證遷移是否乾淨應用、現有查詢仍可執行,並且回滾能恢復到之前狀態。使用遷移後的模式執行應用程式的測試套件。

  5. 使用零停機策略部署: 對於生產環境,使用擴充套件與收縮遷移。第一階段:新增新列/表(擴充套件),不刪除舊結構。第二階段:部署寫入舊和新結構的應用程式程式碼。第三階段:填充資料。第四階段:部署僅使用新結構的程式碼。第五階段:移除舊列/表(收縮)。這確保了無停機並可在每個階段安全回滾。

  6. 驗證與監控: 部署後,使用框架的狀態命令驗證遷移狀態。監控應用程式日誌和資料庫效能以檢測迴歸問題。確認所有遷移後設資料都記錄在框架的版本表中。

支援的技術

  • Alembic: Python、SQLAlchemy、PostgreSQL/MySQL/SQLite
  • Prisma Migrate: TypeScript/JavaScript、Prisma ORM、PostgreSQL/MySQL/SQLite/SQL Server
  • Flyway: Java、基於 SQL 的遷移、所有主流 RDBMS
  • Knex: JavaScript/TypeScript、Node.js、PostgreSQL/MySQL/SQLite
  • Django Migrations: Python、Django ORM
  • Sequelize: JavaScript、Node.js ORM

Usage

描述你需要的模式變更(例如,“在 users 表中新增 phone_number 列”)並指定專案使用的遷移框架。agent 將生成包含升級和降級邏輯的遷移檔案,提供應用方法,並就生產環境的安全部署策略提供建議。

Examples

示例 1:Alembic 遷移 —— 新增列並填充資料

請求: 在 users 表中新增 display_name 列,並通過連線 first_name 和 last_name 填充該列。

生成遷移:

alembic revision --autogenerate -m "add_display_name_to_users"

遷移檔案(versions/20250115_add_display_name_to_users.py):

"""add display_name to users

Revision ID: a1b2c3d4e5f6
Revises: 9z8y7x6w5v4u
Create Date: 2025-01-15 10:30:00.000000
"""
from alembic import op
import sqlalchemy as sa

revision = "a1b2c3d4e5f6"
down_revision = "9z8y7x6w5v4u"
branch_labels = None
depends_on = None


def upgrade():
    # Phase 1: Add the column as nullable (safe, no locks on reads)
    op.add_column("users", sa.Column("display_name", sa.String(300), nullable=True))

    # Phase 2: Backfill existing rows
    users = sa.table(
        "users",
        sa.column("id", sa.Integer),
        sa.column("first_name", sa.String),
        sa.column("last_name", sa.String),
        sa.column("display_name", sa.String),
    )
    op.execute(
        users.update().values(
            display_name=sa.func.concat(
                users.c.first_name, " ", users.c.last_name
            )
        )
    )

    # Phase 3: Set NOT NULL after backfill is complete
    op.alter_column("users", "display_name", nullable=False)


def downgrade():
    op.drop_column("users", "display_name")

應用並驗證:

alembic upgrade head
alembic current   # Confirms: a1b2c3d4e5f6 (head)

示例 2:Prisma Migrate —— 新增 Reviews 模型

請求: 在 Prisma 專案中新增一個與 User 和 Product 關聯的 Review 模型。

更新 prisma/schema.prisma

model Review {
  id        Int      @id @default(autoincrement())
  rating    Int      @db.SmallInt
  comment   String?  @db.Text
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  userId    Int
  productId Int
  user      User     @relation(fields: [userId], references: [id], onDelete: Cascade)
  product   Product  @relation(fields: [productId], references: [id], onDelete: Cascade)

  @@unique([userId, productId])
  @@index([productId])
  @@index([rating])
}

生成並應用遷移:

npx prisma migrate dev --name add_reviews_table

生成的 SQL(prisma/migrations/20250115_add_reviews_table/migration.sql):

CREATE TABLE "Review" (
    "id" SERIAL NOT NULL,
    "rating" SMALLINT NOT NULL,
    "comment" TEXT,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "updatedAt" TIMESTAMP(3) NOT NULL,
    "userId" INTEGER NOT NULL,
    "productId" INTEGER NOT NULL,
    CONSTRAINT "Review_pkey" PRIMARY KEY ("id")
);

CREATE INDEX "Review_productId_idx" ON "Review"("productId");
CREATE INDEX "Review_rating_idx" ON "Review"("rating");
CREATE UNIQUE INDEX "Review_userId_productId_key" ON "Review"("userId", "productId");
ALTER TABLE "Review" ADD CONSTRAINT "Review_userId_fkey"
    FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE;
ALTER TABLE "Review" ADD CONSTRAINT "Review_productId_fkey"
    FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE CASCADE;

最佳實踐

  • 始終為每次遷移編寫顯式的降級/回滾邏輯,以便在部署出現問題時可以安全回滾。永遠不要假設在壓力下能手動撤銷遷移。
  • 使遷移向後相容,通過擴充套件與收縮的方式:先新增新結構,再遷移資料,最後在新程式碼完全部署後再單獨遷移移除舊結構。
  • 不要在未審查的情況下執行自動生成的遷移 —— 自動檢測工具在遇到重新命名欄位時可能會生成破壞性操作(如刪除列)。始終檢查生成的 SQL。
  • 在支援的環境中對 DDL 使用事務(PostgreSQL 會將 DDL 包含在事務中;MySQL 不支援)。對於不支援事務的 DDL 資料庫,需規劃部分失敗恢復方案。
  • 保持遷移小而聚焦 —— 每個遷移檔案對應一個邏輯變更。這使回滾更精細,並更容易識別導致問題的遷移。
  • 在 CI 中執行遷移,針對一次性資料庫以在進入生產前捕獲錯誤。測試中應包含升級和降級路徑。

Edge Cases

  • 大表遷移: 在擁有數百萬行資料的表中新增帶有預設值的 NOT NULL 列,在舊版 PostgreSQL 中可能會鎖表幾分鐘。使用 ADD COLUMN ... DEFAULT ... NOT NULL(PostgreSQL 11+ 無鎖)或先設為可空,分批填充資料,再設定 NOT NULL。
  • 列重新命名: 大多數遷移工具將重新命名視為刪除 + 新增,會導致資料丟失。在 Alembic 中使用 op.alter_column() 或使用原始的 ALTER TABLE ... RENAME COLUMN 執行真正的重新命名。應用前驗證生成的遷移。
  • 併發遷移: 在多例項部署中,確保只有一個例項執行遷移。使用諮詢鎖(Flyway 和 Alembic 支援)或在部署流水線中將遷移作為專用步驟,在推出應用程式例項之前執行。
  • 列舉型別變更: 向 PostgreSQL 列舉新增值是非事務性的。建立新列舉型別,遷移列,然後刪除舊型別。或者使用帶 CHECK 約束的 VARCHAR 以方便修改。
  • 僅資料遷移: 當你需要轉換資料但不改變模式時(例如加密某列的值),仍應使用遷移檔案以確保其在不同環境中可版本化和重現。

🤖 AI 評測

這個資料庫遷移技能質量較好,工作流程清晰完整,涵蓋了主流遷移工具的使用方法和最佳實踐。優點是內容全面、示例豐富,特別是零停機部署策略和邊界情況處理很有價值。不足之處是缺少獨立的示例檔案和配置檔案,資源配套相對單薄。對於需要管理資料庫遷移的開發者來說,這是一個實用的參考技能。

📊 多維度評分

適應性4.3
規範性4.4
有效性4.6
可靠性4
可信度4.9

📁 包含檔案 (3 個)

📄 SKILL.md 8.6 KB
📄 _meta.json 137 B
📄 _skillhub_meta.json 144 B