2019年4月17日

新しいデータモデル構文:スキーマ制御の強化とマイグレーションの簡素化

Prismaの最新リリースでは、改善されたデータモデル構文が導入されました。これにより、Prismaがこれまでデータベースレイアウトに関して行っていた多くの独断的な決定が削除され、開発者により多くの制御権が与えられます。

New Datamodel Syntax: More Schema Control & Simpler Migration

⚠️ この記事は古くなっています。これは現在非推奨となっているPrisma 1に関するものです。Prismaの最新バージョンについては、ドキュメントを参照してください。⚠️

この数ヶ月間、私たちはコミュニティと協力して、Prismaのための改善されたデータモデル仕様を定義してきました。この新しいバージョンはデータモデルv1.1と呼ばれ、本日の安定版リリースで利用可能です。ドキュメントはこちらでご確認ください。

本日より、Prismaの公開デモサーバーは新しいデータモデル構文を使用します。既存のプロジェクトをアップグレードする方法については、ドキュメントまたはこのチュートリアルビデオをご覧ください。


データモデリングへのより柔軟なアプローチ

データモデルは、すべてのPrismaプロジェクトの基盤です。これは、基となるデータベースのスキーマの基礎として機能します。

現在のデータモデルは、リレーション、テーブル/カラムの命名、システムフィールドなど、データベースレイアウトに関して独自の意見を持っています。新しいデータモデル構文は、多くの制限を取り除き、開発者がスキーマをより詳細に制御できるようにします。

データベースレイアウトのより詳細な制御

新しいデータモデル構文によって可能になるいくつかのこと

  • リレーションがリレーションテーブルを使用するか、外部キーを使用するかを指定する
  • モデル/フィールド名は、基となるテーブル/カラム名と異なる場合があります
  • 任意のフィールドを id フィールドとして使用し、「独自のIDを持ち込む」
  • 任意のフィールドを createdAt または updatedAt フィールドとして使用する

マイグレーションの簡素化とイントロスペクションの改善

以前のPrismaバージョンでは、開発者はPRISMA_CONFIGmigrationsフラグを設定することにより、Prismaがデータベースマイグレーションを実行するかどうかを決定する必要がありました。

最新のPrismaバージョンではmigrationsフラグが削除され、開発者は常にデータベースを手動でマイグレーションするか、Prismaを使用してマイグレーションを行うかのいずれかを選択できるようになりました。

また、既存のデータベースのイントロスペクションにも多大な投資を行い、レガシーデータベースでPrismaを使用している開発者や、ある時点で手動マイグレーションを実行する必要がある開発者にとって、スムーズなワークフローを実現しました。


改善されたデータモデル構文の新機能とは?

モデル名とフィールド名を基となるテーブルとカラムにマッピングする

以前のデータモデル構文では、テーブルとカラムは常にデータモデルのモデル名とフィールド名と完全に同じ名前でした。新しい@dbディレクティブを使用すると、基となるデータベースでテーブルとカラムがどのように呼ばれるかを制御できます。

この場合、基となるテーブルはuser、カラムはfull_nameという名前になります。

データベーススキーマでのリレーションの表現方法を決定する

以前のデータモデルは、データベーススキーマにおけるリレーションについて独自の意見を持っていました。それは常にリレーションテーブルとして表現されるというものです。

一方では、これにより既存の任意のリレーションを余分な作業なしに多対多のリレーションに簡単に移行できます。しかし、リレーションテーブルはクエリのコストが高くなることが多いため、この柔軟性にはパフォーマンス上のペナルティが伴う可能性があります。

1対1および1対nのリレーションは外部キーを介して表現できるようになりましたが、m対nのリレーションは引き続きリレーションテーブルとして表現されます。

新しいデータモデルでは、開発者は基となるデータベースでのリレーションの表現方法を完全に制御できます。2つのオプションがあります。

  • インライン参照(つまり、外部キー)を介してリレーションを表現する
  • リレーションテーブルを介してリレーションを表現する

ここに2つのリレーションの例があります(1つはインライン、もう1つはリレーションテーブルを使用)。

インラインリレーションの場合、@relation(link: INLINE)ディレクティブの配置によって、リレーションのどちらの端に外部キーが保存されるかが決まります。この例では、Userテーブルに保存されます。

任意のフィールドを idcreatedAt、または updatedAt として使用する

以前のデータモデルでは、開発者が一意のIDを自動生成したり、レコードの作成/最終更新日時を追跡したりする場合、予約済みのフィールドを使用する必要がありました。

新しい@id@createdAt@updatedAtディレクティブを使用すると、この機能をモデルの任意のフィールドに追加できるようになりました。

より柔軟なID

現在のデータモデルは、データベースレコードのグローバルに一意なIDを生成および保存するために常にCUIDを使用しています。データモデルv1.1では、カスタムIDを維持したり、他のIDタイプ(例:整数、シーケンス、UUID)を使用したりすることも可能になりました。


新しいデータモデル構文を始める

新しいデータモデルを学ぶための短いチュートリアルを2つ用意しました。

より詳細なチュートリアルや既存のデータベースでの開始手順については、ドキュメントをご覧ください。

前提条件:最新のPrisma CLIをインストールする

Prisma CLIの最新バージョンをインストールするには、以下を実行します

DockerでPrismaを実行する場合、Dockerイメージを1.31にアップグレードする必要があります。

オプションA:古いPrismaバージョンからのアップグレード

既存のPrismaプロジェクトをアップグレードする際には、prisma introspectを実行するだけで新しい構文のデータモデルを生成できます。正確な手順は、以下のセクションとこのビデオで例とともに説明されています。

1. 古いデータモデルのセットアップ

(古い)データモデルを使用しているPrismaプロジェクトが既に稼働中であると仮定します。

古いデータモデルを使用すると、Prismaによって基となるデータベースに以下のテーブルが作成されます

  • User
  • Profile
  • Post
  • Category
  • _CategoryToPost
  • _PostToUser
  • _ProfileToUser
  • _RelayId

各リレーションはリレーションテーブルを介して表現されます。_RelayIdテーブルは、レコードをそのIDで識別するために使用されます。古いデータモデル構文では、これらはPrismaが行う決定であり、回避することはできませんでした。

2. Prismaサーバーのアップグレード

Prismaサーバーをデプロイするために使用するDocker Composeファイルで、prismagraphql/prismaイメージに最新の1.31 Prismaバージョンを使用していることを確認してください。例:

稼働中のPrismaサーバーをアップグレードする

3. イントロスペクションによる新しいデータモデルの生成

もし現在prisma deployを実行すると、古い構文のデータモデルを更新されたPrismaサーバーにデプロイしようとしているため、Prisma CLIがエラーをスローします。

これらのエラーを修正する最も簡単な方法は、イントロスペクションを介して新しい構文で書かれたデータモデルを生成することです。prisma.ymlがあるディレクトリ内で以下のコマンドを実行してください。

これによりデータベースがイントロスペクトされ、新しい構文のデータモデルがdatamodel-TIMESTAMP.prisma(例:datamodel-1554394432089.prisma)という名前で生成されます。上記の例では、以下のデータモデルが生成されます。

4. 新しいデータモデルのデプロイ

最後のステップは、古いdatamodel.prismaファイルを削除し、生成されたデータモデルをdatamodel.prismaにリネームすることです(これにより、prisma.ymldatamodelプロパティが新しい構文を使用している生成ファイルを参照するようになります)。

これが完了したら、以下を実行できます。

5. データベーススキーマの最適化

イントロスペクションはデータベースレイアウトを何も変更しないため、すべてのリレーションは依然としてリレーションテーブルとして表現されます。古い1対1および1対nのリレーションを外部キーを使用するように移行する方法を学ぶには、こちらのドキュメントをご覧ください。

オプションB:ゼロから始める

既存のPrismaプロジェクトをアップグレードする方法を学んだ後、今度はゼロから始めるシンプルなセットアップについて説明します。

1. 新しいPrismaプロジェクトを作成する

まず、新しいPrismaプロジェクトをセットアップしましょう。

対話型ウィザードで、以下を選択します。

  1. 新しいデータベースを作成」を選択
  2. PostgreSQL」を選択(またはお好みでMySQL)
  3. 好みの言語でクライアントを選択(クライアントは使用しないためオプション

Docker経由でPrismaサーバーとデータベースを起動する前に、データベースのポートマッピングを有効にしてください。これにより、後でローカルのDBクライアント(PosticoTablePlusなど)を使用してデータベースに接続できるようになります。

生成されたdocker-compose.ymlで、データベースのDockerイメージ構成にある以下の行のコメントを解除します。

2. データモデルの定義

新しいPrismaの機能を活用するデータモデルを定義しましょう。datamodel.prismaを開き、内容を以下に置き換えます。

このデータモデル定義に関するいくつかの重要な点

  • 各モデルは、@dbディレクティブを使用して、モデル名と同じで小文字に変換された名前のテーブルにマッピングされます。
  • 以下のリレーションがあります
    • 1対1 UserProfile
    • 1対多 UserPost
    • 多対多 PostCategory
  • 1対1 UserProfile 間のリレーションは、Userモデルで@relation(link: INLINE)としてアノテーションされています。これは、リレーションが存在する場合(profileフィールドは必須ではないため、リレーションがNULLの場合もあります)、データベースのuserレコードがprofileレコードへの参照を持つことを意味します。INLINEの代替としてTABLEがあり、その場合Prismaは専用のリレーションテーブルを介してリレーションを追跡します。
  • 1対多 UserPost 間のリレーションは、postテーブルのauthorカラムを介してリレーションがインラインで追跡されます。つまり、@relation(link: INLINE)ディレクティブはPostモデルのauthorフィールドに推論されます。
  • 多対多 PostCategory 間のリレーションは、PostToCategoryという専用のリレーションテーブルを介して追跡されます。このリレーションテーブルはデータモデルの一部であり、@relationTableディレクティブでアノテーションされています。
  • 各モデルには、@idディレクティブでアノテーションされたidフィールドがあります。
  • Userモデルの場合、データベースは@createdAtディレクティブでアノテーションされたフィールドを介して、レコードが作成された日時を自動的に追跡します。
  • Postモデルの場合、データベースは@createdAtおよび@updatedAtディレクティブでアノテーションされたフィールドを介して、レコードが作成および更新された日時を自動的に追跡します。

3. データモデルのデプロイ

次のステップで、Prismaはこのデータモデルを基となるデータベースにマッピングします。

Category

テーブル

インデックス

インデックス名インデックスアルゴリズム一意性カラム名category_pkeyBTREETRUEid
Post

テーブル

インデックス

インデックス名インデックスアルゴリズム一意性カラム名post_pkeyBTREETRUEid
PostToCategory

テーブル

インデックス

インデックス名インデックスアルゴリズム一意性カラム名post_to_category_AB_uniqueBTREETRUEcategory,postpost_to_category_BBTREEFALSEpost
Profile

テーブル

インデックス

インデックス名インデックスアルゴリズム一意性カラム名profile_pkeyBTREETRUEid
User

テーブル

インデックス

インデックス名インデックスアルゴリズム一意性カラム名user_pkeyBTREETRUEidhello-datamodel$dev.user.email._UNIQUEBTREETRUEemail

4. Prisma Adminでのデータの表示と編集

ここからは、プログラムでデータベースのデータにアクセスしたい場合、Prismaクライアントを使用できます。以下では、Prisma Adminを使用してデータとやり取りする方法を重点的に説明します。

TablePlusを使用してデータベースに接続し、基となるデータベーススキーマを探索する方法については、ドキュメントをご覧ください。

Prisma Adminでデータにアクセスするには、PrismaプロジェクトのAdminエンドポイント、https://:4466/_adminにアクセスする必要があります。

Access your data in Prisma Admin


ご意見とアイデアを共有してください

新しいデータモデル構文はすでにコミュニティからの多くの要望を取り入れていますが、さらに改善の余地があると考えています。例えば、このデータモデルにはまだ多列インデックスポリモーフィックリレーションが提供されていません。

現在、既存のSDLのバリエーションとなる新しいデータモデリング言語の開発に取り組んでいます。

新しいデータモデルについてのご意見をお聞かせください。フィードバックリポジトリでissueを開くか、Spectrumでの議論に参加して、ご意見を共有してください。

次の投稿をお見逃しなく!

Prismaニュースレターに登録する

© . All rights reserved.