跳到主要內容

原型化您的 schema

Prisma CLI 有一個專門用於原型化 schema 的命令:db push

db push 使用與 Prisma Migrate 相同的引擎來同步您的 Prisma schema 與資料庫 schema。db push 命令

  1. 內省資料庫以推斷並執行所需的更改,使您的資料庫 schema 反映 Prisma schema 的狀態。

  2. 預設情況下,更改應用到資料庫 schema 後,會觸發生成器(例如 Prisma Client)。您無需手動呼叫 prisma generate

  3. 如果 db push 預計更改可能導致資料丟失,它將

    • 丟擲錯誤
    • 如果您仍要進行更改,則需要 --accept-data-loss 選項

注意:

  • db push 不與遷移互動,也不依賴遷移。遷移表 _prisma_migrations 不會被建立或更新,也不會生成任何遷移檔案。
  • 當使用 PlanetScale 時,我們建議您使用 db push 而不是 migrate。有關詳細資訊,請參閱我們的“開始使用”文件,根據您的情況選擇“從頭開始”“新增到現有專案”

選擇 db push 還是 Prisma Migrate

db push 適用於以下情況:

  • 您希望在本地**快速原型化並迭代** schema 設計,而無需將這些更改部署到其他環境,例如其他開發人員或暫存和生產環境。
  • 您優先考慮達到**期望的最終狀態**,而不是實現該最終狀態所執行的更改或步驟(無法預覽 db push 所做的更改)
  • 您不需要控制 schema 更改如何影響資料。無法編排 schema 和資料遷移——如果 db push 預計更改將導致資料丟失,您可以選擇使用 --accept-data-loss 選項接受資料丟失,或者停止該過程。無法自定義更改。

請參閱“使用 db push 進行 schema 原型化”以瞭解如何以這種方式使用 db push 的示例。

在以下情況下**不建議**使用 db push

  • 您希望在不丟失資料的情況下在其他環境中複製您的 schema 更改。您可以使用 db push 進行原型化,但您應該使用遷移來提交 schema 更改並將其應用於其他環境。
  • 您希望對 schema 更改的執行方式進行細粒度控制——例如,重新命名列而不是刪除它並建立新列
  • 您希望跟蹤資料庫 schema 隨時間變化的更改。db push 不會建立任何允許您跟蹤這些更改的工件。
  • 您希望 schema 更改是可逆的。您可以再次使用 db push 恢復到原始狀態,但這可能會導致資料丟失。

我可以同時使用 Prisma Migrate 和 db push 嗎?

是的,您可以在開發工作流中同時使用 db push 和 Prisma Migrate。例如,您可以

  • 在專案開始時使用 db push 原型化 schema,並在對初稿滿意時初始化遷移歷史記錄
  • 使用 db push 原型化對現有 schema 的更改,然後執行 prisma migrate dev 從您的更改中生成遷移(您將被要求重置)

原型化新 schema

以下場景演示瞭如何使用 db push 將新 schema 與空資料庫同步,並演進該 schema——包括當 db push 檢測到更改將導致資料丟失時會發生什麼。

  1. 建立 schema 的初稿

    generator client {
    provider = "prisma-client-js"
    }

    datasource db {
    provider = "postgresql"
    url = env("DATABASE_URL")
    }

    model User {
    id Int @id @default(autoincrement())
    name String
    jobTitle String
    posts Post[]
    profile Profile?
    }

    model Profile {
    id Int @id @default(autoincrement())
    biograpy String // Intentional typo!
    userId Int @unique
    user User @relation(fields: [userId], references: [id])
    }

    model Post {
    id Int @id @default(autoincrement())
    title String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    }

    model Category {
    id Int @id @default(autoincrement())
    name String @db.VarChar(50)
    posts Post[]

    @@unique([name])
    }
  2. 使用 db push 將初始 schema 推送到資料庫

    npx prisma db push
  3. 建立一些示例內容

    const add = await prisma.user.create({
    data: {
    name: 'Eloise',
    jobTitle: 'Programmer',
    posts: {
    create: {
    title: 'How to create a MySQL database',
    content: 'Some content',
    },
    },
    },
    })
  4. 進行增量更改——例如,建立一個新的必填欄位

    // ... //

    model Post {
    id Int @id @default(autoincrement())
    title String
    description String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    }

    // ... //
  5. 推送更改

    npx prisma db push

    db push 將失敗,因為您不能向現有內容的表中新增必填欄位,除非您提供預設值。

  6. 重置資料庫中的**所有資料**並重新應用遷移。

    npx prisma migrate reset

    **注意**:與 Prisma Migrate 不同,db push 不會生成您可以修改以保留資料的遷移,因此最適合在開發環境中進行原型設計。

  7. 繼續演進您的 schema,直到它達到相對穩定的狀態。

  8. 初始化遷移歷史記錄

    npx prisma migrate dev --name initial-state

    達到初始原型的步驟不會被保留——db push 不會生成歷史記錄。

  9. 將您的遷移歷史記錄和 Prisma schema 推送到版本控制(例如 Git)。

此時,您的原型設計的最終草稿將保留在遷移中,並可以推送到其他環境(測試、生產或您的團隊其他成員)。

使用現有遷移歷史記錄進行原型化

以下場景演示瞭如何使用 db push 對已存在遷移歷史記錄的 Prisma schema 進行更改的原型設計。

  1. 檢查最新的 Prisma schema 和遷移歷史記錄

    generator client {
    provider = "prisma-client-js"
    }

    datasource db {
    provider = "postgresql"
    url = env("DATABASE_URL")
    }

    model User {
    id Int @id @default(autoincrement())
    name String
    jobTitle String
    posts Post[]
    profile Profile?
    }

    model Profile {
    id Int @id @default(autoincrement())
    biograpy String // Intentional typo!
    userId Int @unique
    user User @relation(fields: [userId], references: [id])
    }

    model Post {
    id Int @id @default(autoincrement())
    title String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    }

    model Category {
    id Int @id @default(autoincrement())
    name String @db.VarChar(50)
    posts Post[]

    @@unique([name])
    }
  2. 原型化您的新功能,這可以涉及任意數量的步驟。例如,您可以

    • 建立一個 tags String[] 欄位,然後執行 db push
    • 將欄位型別更改為 tags Tag[] 並新增一個名為 Tag 的新模型,然後執行 db push
    • 改變主意並恢復原始的 tags String[] 欄位,然後呼叫 db push
    • 手動更改資料庫中的 tags 欄位——例如,新增一個約束

    在嘗試了幾種解決方案後,最終的 schema 更改如下所示

    model Post {
    id Int @id @default(autoincrement())
    title String
    description String
    published Boolean @default(true)
    content String @db.VarChar(500)
    authorId Int
    author User @relation(fields: [authorId], references: [id])
    categories Category[]
    tags String[]
    }
  3. 要建立新增新 tags 欄位的遷移,請執行 migrate dev 命令

    npx prisma migrate dev --name added-tags

    Prisma Migrate 將提示您重置,因為您在原型設計期間手動和使用 db push 所做的更改不屬於遷移歷史記錄。

    √ Drift detected: Your database schema is not in sync with your migration history.

    We need to reset the PostgreSQL database "prototyping" at "localhost:5432".
    警告

    這將導致全部資料丟失。

    npx prisma migrate reset
  4. Prisma Migrate 會重放現有的遷移歷史記錄,根據您的 schema 更改生成新的遷移,並將這些更改應用到資料庫。

提示

當使用 migrate dev 時,如果您的 schema 更改意味著種子指令碼將不再起作用,您可以使用 --skip-seed 標誌來忽略種子指令碼。

此時,您的原型設計的最終結果將保留在遷移中,並可以推送到其他環境(測試、生產或您的團隊其他成員)。

© . This site is unofficial and not affiliated with Prisma Data, Inc.