メインコンテンツへスキップ

スキーマのプロトタイプ作成

Prisma CLIには、スキーマのプロトタイプ作成専用のコマンド db push があります。

db pushはPrisma Migrateと同じエンジンを使用して、Prismaスキーマとデータベーススキーマを同期します。db pushコマンドは、

  1. データベースをイントロスペクトして推論し、データベーススキーマがPrismaスキーマの状態を反映するために必要な変更を実行します。

  2. デフォルトでは、データベーススキーマに変更が適用されると、ジェネレーター(Prisma Clientなど)がトリガーされます。手動でprisma generateを呼び出す必要はありません。

  3. db pushは、変更がデータ損失につながる可能性があると予測する場合、以下の処理を行います。

    • エラーをスローします
    • それでも変更を行いたい場合は、--accept-data-lossオプションを要求します

注意事項:

  • db pushはマイグレーションと相互作用したり、依存したりしません。マイグレーションテーブル_prisma_migrationsは作成または更新されず、マイグレーションファイルも生成されません。
  • PlanetScaleと連携する場合、migrateの代わりにdb pushを使用することをお勧めします。詳細については、状況に応じて「最初から始める」または「既存のプロジェクトに追加する」のいずれかの導入ドキュメントを参照してください。

db pushまたはPrisma Migrateの選択

db pushは次の場合にうまく機能します。

  • 他の環境(他の開発者、ステージング環境、本番環境など)にデプロイする必要なく、ローカルでスキーマ設計を素早くプロトタイプ作成し、反復したい場合。
  • 望ましい最終状態に到達することを優先し、その最終状態に到達するために実行された変更や手順を優先しない場合(db pushによって行われる変更をプレビューする方法はありません)。
  • スキーマ変更がデータにどのように影響するかを制御する必要がない場合。スキーマとデータのマイグレーションを調整する方法はありません。db pushが変更によってデータ損失が生じると予測した場合、--accept-data-lossオプションでデータ損失を受け入れるか、プロセスを停止することができます。変更をカスタマイズする方法はありません。

このようなdb pushの使用例については、db pushによるスキーマのプロトタイプ作成を参照してください。

db pushは次の場合には推奨されません

  • データ損失なく他の環境でスキーマ変更を複製したい場合。プロトタイプ作成にはdb pushを使用できますが、スキーマ変更をコミットし、他の環境に適用するにはマイグレーションを使用する必要があります。
  • スキーマ変更がどのように実行されるかを細かい粒度で制御したい場合。例えば、列を削除して新しいものを作成する代わりに名前を変更するなど。
  • 時間の経過とともにデータベーススキーマに加えられた変更を追跡したい場合。db pushはこれらの変更を追跡するためのアーティファクトを作成しません。
  • スキーマ変更を元に戻せるようにしたい場合。元の状態に戻すために再度db pushを使用できますが、これによりデータ損失が生じる可能性があります。

Prisma Migrateとdb pushを一緒に使用できますか?

はい、開発ワークフローでdb pushとPrisma Migrateを一緒に使用することができます。例えば、次のように使用できます。

  • プロジェクトの開始時にdb pushを使用してスキーマをプロトタイプ作成し、最初のドラフトに満足したらマイグレーション履歴を初期化します。
  • db pushを使用して既存のスキーマへの変更をプロトタイプ作成し、その後prisma migrate devを実行して、変更からマイグレーションを生成します(リセットが要求されます)。

新しいスキーマのプロトタイプ作成

次のシナリオは、db pushを使用して新しいスキーマを空のデータベースと同期させ、そのスキーマを進化させる方法を示します。これには、db pushが変更によってデータ損失が生じると検出した場合に何が起こるかを含みます。

  1. スキーマの最初のドラフトを作成します

    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を使用して初期スキーマをデータベースにプッシュします。

    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. 比較的安定した状態に達するまでスキーマを進化させ続けます。

  8. マイグレーション履歴を初期化します。

    npx prisma migrate dev --name initial-state

    初期プロトタイプに到達するために実行された手順は保持されません。db pushは履歴を生成しないからです。

  9. マイグレーション履歴とPrismaスキーマをソース管理(例:Git)にプッシュします。

この時点で、プロトタイプ作成の最終ドラフトはマイグレーションとして保持され、他の環境(テスト、本番、またはチームの他のメンバー)にプッシュすることができます。

既存のマイグレーション履歴を使用したプロトタイプ作成

次のシナリオは、マイグレーション履歴が既に存在するPrismaスキーマへの変更をプロトタイプ作成するためにdb pushを使用する方法を示します。

  1. 最新のPrismaスキーマとマイグレーション履歴をチェックアウトします。

    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フィールドに手動で変更を加えます。例えば、制約を追加します。

    いくつかの解決策を試した後、最終的なスキーマ変更は次のようになります。

    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

    プロトタイプ作成中に手動で行った変更やdb pushで行った変更はマイグレーション履歴の一部ではないため、Prisma Migrateはリセットを促します。

    √ 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は、既存のマイグレーション履歴をリプレイし、スキーマ変更に基づいて新しいマイグレーションを生成し、それらの変更をデータベースに適用します。

ヒント

migrate devを使用する際、スキーマ変更によりシードスクリプトが動作しなくなる場合、--skip-seedフラグを使用してシードスクリプトを無視できます。

この時点で、プロトタイプ作成の最終結果はマイグレーションとして保持され、他の環境(テスト、本番、またはチームの他のメンバー)にプッシュすることができます。

© . All rights reserved.